【问题标题】:How to pass custom props into QueryRenderer render function?如何将自定义道具传递给 QueryRenderer 渲染函数?
【发布时间】:2018-01-28 07:07:17
【问题描述】:

给定以下 QueryRenderer 组件:

class ProjectQueryRenderer extends Component {
  constructor(props) {
    super(props);
    this.renderProjectList = this.renderProjectList.bind(this);
  }

  renderProjectList({ error, props }) {
    if (props) {
      return (
        <ProjectList
          connection={props.viewer.allProjects}
          onSelectProject={this.props.onSelectProject}
          selectedProject={this.props.selectedProject}
        />
      );
    }
  }

  render() {
    return (
      <QueryRenderer
        environment={environment}
        query={ProjectsQuery}
        render={this.renderProjectList}
      />
    );
  }
}

ProjectQueryRenderer.propTypes = {
  onSelectProject: Proptypes.func.isRequired,
  selectedProject: Proptypes.string.isRequired,
};

我遇到的问题是,当我自己的 selectedProject 属性更改值时,renderProjectList 不会再次执行。 render 方法显然确实被触发了,但是由于 QueryRenderer 的任何属性都没有改变,renderProjectList 也没有被调用。

处理这个问题的最佳方法是什么?

【问题讨论】:

    标签: reactjs relayjs relay relaymodern


    【解决方案1】:

    我找到了一个解决方案,每次我注入的一个道具发生变化时,它都会成功地重新呈现我的列表组件(不执行 api 请求)。我必须在 render 函数中定义我的组件,以便我可以访问新的 prop 值。

    作为功能组件的结果如下:

    const ProjectQueryRenderer = ({ onSelectProject, selectedProject }) => {
      const comp = ({ error, props }) => {
        if (props) {
          return (
            <ProjectList
              connection={props.viewer.allProjects}
              onSelectProject={onSelectProject}
              selectedProject={selectedProject}
            />
          );
        }
      };
      return (
        <QueryRenderer
          environment={environment}
          query={ProjectsQuery}
          render={comp}
        />
      );
    };
    

    【讨论】:

    • 这种方法的缺点是每次ProjectQueryRenderer 需要渲染时,您都会为comp 函数创建一个新定义。
    【解决方案2】:

    除了将渲染函数传递给QueryRenderer,您还可以将整个 ProjectList 组件作为属性以及该组件需要从父组件渲染的任何道具传递。他们额外的道具在QueryRenderer 中显示为other。见下文:

    class ProjectQueryRenderer extends Component {
      render() {
        return (
          <QueryRenderer
            environment={environment}
            query={ProjectsQuery}
            component={ProjectList}
            onSelectProject={this.props.onSelectedProject}
            selectProject={this.props.selectedProject}
          />
        );
      }
    }
    
    ProjectQueryRenderer.propTypes = {
      onSelectProject: Proptypes.func.isRequired,
      selectedProject: Proptypes.string.isRequired,
    };
    

    现在是 QueryRenderer

    class QueryRenderer extends Component {
    
      render() {
        const {environment, query, component, ...other} = this.props 
    
        // parameters to component that QueryRenderer computes
        // based on environment, query, etc...
        // plus also pass in all the extra props that are coming from
        // ProjectQueryRenderer (like onSelectProject)
        const computedProp = //something
    
        return (
         <div>
           <component computedProp={computedProp} {...other} />
         </div>
       )
      }
    }
    

    这样,ProjectQueryRenderer 和 QueryRenderer 都可以将 props 传递给任意组件到 QueryRenderer 中,您也可以在其他类型的组件中重用 QueryRenderer。

    【讨论】:

    • 不确定我是否理解正确。上面的示例给出了Uncaught TypeError: this.props.render is not a function 错误。
    • 我将 render 属性名称更改为 component,但您可以自行决定是否为它找到合适的名称。也许我的解决方案并不完全是您正在寻找的。我又在看它,我正在工作。 ProjectList 是否依赖于从 ProjectQueryRendererQueryRenderer 过去的属性?如果是这样,这个问题还有另一种解决方案。
    猜你喜欢
    • 2018-03-27
    • 2020-12-22
    • 2020-01-06
    • 1970-01-01
    • 2011-10-13
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多