【问题标题】:How to pass props (both states and functions) to the child router component如何将道具(状态和功能)传递给子路由器组件
【发布时间】:2016-10-28 13:20:04
【问题描述】:

请多多包涵。我刚刚学习 Reactjs 并停留在一个点上。

app-client.js

ReactDOM.render((
    <Router history={hashHistory}>
        <Route path="/" component={APP}>
            <IndexRoute component={Audience}/>
            <Route path="speaker" component={Speaker}/>
            <Route path="board" component={Board}/>
        </Route>
    </Router>
), document.getElementById('react-container'));

APP.js

var APP = React.createClass({

    getInitialState() {
        return {
            status: 'disconnected',
            title: ''
        }
    },

  emit(eventName, payload) {
        this.socket.emit(eventName, payload);
    },

  render() {
    return (
        <div>
            <Header title={this.state.title} status={this.state.status}/>
            {this.props.children}
        </div>
        );
  }
});

Audience.js:

var Audience = React.createClass({
    render() {
        return (<h1>Audience: {this.props.title}</h1>);
    }
});

页面显示所有组件,但this.props.title 未显示在页面中,emit() 未触发。如何在APP上将道具传递给{this.props.children}(即Audience或Speaker)?

更新

APP.js 渲染():

render() {
    const _this = this;
    return (
        <div>
            <Header title={this.state.title} status={this.state.status}/>
            { React.children.map(this.props.children, (child, index) => {
                    //Get props of child
                   // const childProps = child.props;

                   //do whatever else you need, create some new props, change existing ones
                   //store them in variables

                   return React.cloneElement(child, {
                       // ...childProps, //these are the old props if you don't want them changed
                       // ...someNewProps,
                       // someOldPropOverwritten, //overwrite some old the old props
                       ..._this.state,
                       emit: _this.emit
                   });
                })
            }
        </div>
        );
  }

});

【问题讨论】:

  • 使用React.children.map(this.props.children... 和大写Children

标签: javascript reactjs react-router


【解决方案1】:

React 为您提供的 API 组合可以解决您不确定如何实现的问题 (way to pass props to components rendered by this.props.children)

首先,你需要看看cloneElement

它基本上会采用一个 React 元素,克隆它,然后返回另一个带有道具,您可以完全根据您的需要更改、更改或替换。

此外,将它与 Children Utilities 结合使用 - 循环遍历提供给顶级组件的子元素,并对每个元素分别进行必要的更改。

你可以找到一个更全面的答案,我在一个非常相似的主题上提供了一个最近被问到的问题:

changing-components-based-on-url-with-react-router

基本上是这样的:

render() {
  const _this = this;
  return (
    {React.Children.map(this.props.children, (child, index) => {
       //Get props of child
       const childProps = child.props;

       //do whatever else you need, create some new props, change existing ones
       //store them in variables

       return React.cloneElement(child, {
           ...childProps, //these are the old props if you don't want them changed
           ...someNewProps,
           someOldPropOverwritten, //overwrite some old the old props
           ..._this.state,
           someFn: _this.someFn,
           ...
       });
     )}
}

【讨论】:

  • 假设,我正在通过所有状态{React.cloneElement(this.props.children, { ...this.state } )}。这确实传递了所有道具,但如果我必须将函数道具传递给孩子,我该怎么做?
  • 如果您已经在某处定义了函数,只需传递参考:propFn: fnReference ..
  • 请。谢谢。
  • 是的,将Children 设为大写即可。我接受了你的回答,因为它是正确的。但是如果你有时间,能不能请你解开我的一些疑惑,我真的很想学习。 1) 为什么使用_this 而不是this。 2) 什么是...childProps...someNewPropssomeOldPropOverwritten
  • 好的!非常感谢您的参与。这确实帮助我了解更多。
【解决方案2】:

使用 Api React.children 迭代父元素并使用 React.cloneElement 克隆每个元素

var Child = React.createClass({
  render: function() {
        return (<div onClick={() =>  this.props.doSomething(this.props.value)}>Click Me</div>);
  }
});


var Audience = React.createClass({
  render: function() {
        return (<div>{this.props.title}</div>);
  }
});

var App = React.createClass({

  doSomething: function(value) {
    console.log('child with value:', value);
  },

  render: function() {
    var childrenWithProps = React.Children.map(this.props.children, (child) => React.cloneElement(child, { title: "test", doSomething: this.doSomething }));
    return <div>{childrenWithProps}</div>
  }
});

ReactDOM.render(
  <App>
    <Child value="2"/>
    <Audience/>
  </App>,
    document.getElementById('container')
);

https://jsfiddle.net/ysq2281h/

【讨论】:

  • 假设,我正在通过所有状态{React.cloneElement(this.props.children, { ...this.state } )}。这确实传递了所有道具,但如果我必须将function 作为道具传递给孩子,我该怎么做?
  • 请检查,我已经更新了示例。您可以将道具功能传递给具有相同模式的孩子
猜你喜欢
  • 1970-01-01
  • 2020-10-08
  • 1970-01-01
  • 2020-08-20
  • 2021-01-03
  • 2020-03-26
  • 2015-09-01
  • 2019-11-16
  • 2020-06-04
相关资源
最近更新 更多