【问题标题】:Filter data in react based on parent prop根据父道具过滤数据
【发布时间】:2018-02-05 16:07:06
【问题描述】:

如何根据父 prop 过滤组件中的数据?

我要比较的数据包含以下内容:

{
   "id": "5a7847508f9337cf77712128",
   "index": 0,
   "projectName": "Ovolo",
   "location": "Stoddard Place, Riverton, New York, 3571"
},
{
   "id": "5a7847503101a8ef7f7d3c30",
   "index": 1,
   "projectName": "Isonus",
   "location": "Elliott Walk, Magnolia, Minnesota, 4488"
}...

我的组件看起来像这样:

import React, {Component} from 'react';
import data from "../data/projects.json";

const ProjectTitle = data.filter((projects, props) => {
    if (projects.id === props.project_id ) 
    var title = projects.projectName;
    return title;
});

class ProjectName extends Component {
    constructor() {
        super();

        this.state = {
            projectTitle: ProjectTitle
        }
    }

    componentDidMount() {
      this.setState({
        projectTitle: ProjectTitle
      });
    }

    render() {
        return (
            <h4 className="projectName">
                { this.state.projectTitle }
            </h4>
        );
    }
}

export default ProjectName;

基本上,我想将父组件中的 props.project_id 与我的数据中与 id 匹配的第一个项目进行匹配,因此我可以使用该组件显示 projectName。目前,我尝试过的那个没有返回项目的名称。我是新手,所以我需要帮助和指导,也许一个例子或参考可能会有所帮助。

【问题讨论】:

    标签: javascript arrays reactjs redux


    【解决方案1】:

    据我所知,基本上您想观察从父级发送的不同 project_id 并取决于要过滤数据的对象。

    您可以做的一件事是使用 componentWillReceiveProps 生命周期来监视新的道具。并且还可以通过componentDidMount生命周期来设置项目标题。

    您还需要更改 projectTitle 函数

    const ProjectTitle = (projectId) => {
      const project = data.filter((projects) => {
        if (projects.id === projectId ) {
           return true;
        }
        return false
    });
    if(project) {
      return projects.projectName;
    }
    return project
    }
    
    componentWillReceiveProps(nextProps) {
       const {project_id} = nextProps
       const newProjectTitle = ProjectTitle(project_id)
       this.setState({
        projectTitle: newProjectTitle,
       })
    }
    
    componentDidMount() {
    const {project_id} = this.props
       const newProjectTitle = ProjectTitle(project_id)
       this.setState({
        projectTitle: newProjectTitle,
       })
    }
    

    通过添加 componentWIllReceiveprops 和 componentDidMount 你可以 每当传递新的 project_id 时动态更改项目名称 作为道具。你也可以像这样使用构造函数来初始化状态

    constructor(props) {
      super(props) 
        this.state = {
        projectTitle: ProjectTitle(props.project_id),
     }
    }
    

    更多参考请参考lifecycle methods in react

    【讨论】:

      【解决方案2】:

      不知道为什么它不能完全正常工作,但你在课堂外创建的 ProjectTitle 并不适合我。我认为您将其分配给了该州,但这并没有按预期工作。您应该在React lifecycle 的componentWillMount 函数中进行过滤(或查找)操作。找到项目后,您执行 setState,它应该可以工作。

      class ProjectName extends Component {
              constructor() {
                  super();
      
                  this.state = {
                      projectTitle: ''
                  }
              }
      
              componentWillMount() {
                const project = data.find(project => project.id === this.props.project_id);
                if (project) {
                    this.setState({
                      projectTitle: project.projectName
                    });
                }
              }
      
              render() {
                  return (
                      <h4 className="projectName">
                          {this.state.projectTitle}
                      </h4>
                  );
              }
          }
      
          export default ProjectName;
      

      【讨论】:

      • 请避免纯代码回答;添加简要说明您所做的更改以回答此问题。
      • 代码看起来是正确的,但我认为解释 OP 有什么不正确会让你投赞成票;)
      • 如果组件更新,这将不起作用,您需要复制componentWillReceiveProps回调中的逻辑并检查project_id是否会改变,如果是则更新状态。最好将此逻辑移动到组件的构造函数而不是componentWillMount
      • @TiagoHenriqueEngel 更新和 componentWillReceiveProps 看起来超出了 OP 的范围,询问您是否问我。如果需要,当然可以。
      • 嗯,这是看待它的一种方式。您建议他/她实施一个行不通的解决方案。我认为这在问题的范围内
      【解决方案3】:

      假设 props.project_id 是 ProjectName 的道具,最简单的解决方案是将过滤器移至渲染函数。此外,如果您想查找一条记录,请使用 find 而不是 filter

      render() {
          const project = data.find(( {id} ) => id === this.props.project_id)
          return (
              <h4 className="projectName">
                  { project && project.title }
              </h4>
          );
      }
      

      您可以按照其他建议的方式在组件创建期间设置状态,但是您必须在 componentWillReceiveProps 中执行相同操作,这会产生很多不必要的复杂性。

      如果性能是一个问题(通常不是)并且您希望每个 id 只查找一次项目,请使用 memoized 函数并将逻辑保留在渲染函数中。这样就简单多了,效果也一样。

      【讨论】:

        猜你喜欢
        • 2023-03-31
        • 1970-01-01
        • 2021-03-07
        • 2018-05-25
        • 2019-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-11
        相关资源
        最近更新 更多