2017-08-19 93 views
1

鉴于以下QueryRenderer组件:如何将自定义道具传递给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, 
}; 

我的问题是,renderProjectList不会被再次执行时,我自己selectedProject道具的变化值。 render方法显然确实被触发,但由于QueryRenderer的任何一个道具都没有被更改,所以renderProjectList也没有被调用。

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

回答

0

除了将渲染函数传递给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可以通过道具成任意的成分进入QueryRenderer并且可以重复使用QueryRenderer将其他类型的组件也是如此。

+0

不知道我正确地理解这一点。上面的例子给出了一个'Uncaught TypeError:this.props.render不是函数错误。 – nickdecooman

+0

我将'render'道具名称更改为'component',但由您自己决定合适的名称。也许我的解决方案并不完全是你要找的。我正在看着它,我正在工作。 “ProjectList”是否依赖于来自'ProjectQueryRenderer'和'QueryRenderer'的属性?如果是这样,这个问题还有另一种解决方案。 – aherriot

0

我发现了一个解决方案,可以在每次我的一个注入道具发生变化时成功提交我的列表组件(不执行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} 
    /> 
); 
}; 
+0

这种方法的缺点是每次需要渲染'ProjectQueryRenderer'时都会为'comp'函数创建一个新的定义。 – aherriot

相关问题