如何在React.js中将道具从一个类传递到另一个类

时间:2016-11-17 18:56:23

标签: javascript class reactjs components

我对React很新。我正在练习创建一个非常简单的九格网框,用户可以使用下拉菜单选择他们想要使用的颜色。唯一的问题是,我无法弄清楚如何将包含它的类(ColorPicker)中的变量传递给包含网格的类(Box)。谁能给我一些关于如何做到这一点的指示?

我仍然习惯将道具传递给其他班级。

以下是CodePen的链接:http://codepen.io/anfperez/pen/RorKge

这是我的代码

//this displays the color selections for the boxes: red, green, and blue
var ColorPicker = React.createClass({

handleChange: function(e) {
    var newColor = e.target.value;
    this.props.onChange(color);

},

render: function() {

return (
    <div>
        <select id="pick-colors" onChange={this.handleChange}>
            <option value="red">
                Red 
            </option>

            <option value="green">
                Green 
            </option>

            <option value="blue">
                Blue 
            </option>

        </select>

    </div>
    )
}
});

//contains the boxes that will eventually change color
var Box = React.createClass({
getInitialState: function() {
    return {
      //boxes are initially white
        color: 'white'
    };
},

    changeColor: function(newColor) {
        var newColor = this.state.color;
        this.setState({
            color: newColor
        });

    },

render: function() {
    return (
    <div >
    <div className='box' style={{background:this.state.color}} onClick={this.changeColor}> 
    </div>
    </div>
    );
}
});

7 个答案:

答案 0 :(得分:20)

React中的道具从父母传递给孩子。例如,如果您有一个呈现子类的父类,则父类现在可以将props传递给子类。这是一个例子。

class Parent extends React.Component {
    render() {
        return (
            <Child example="foo" />
        )
    }
}

class Child extends React.component {
    render() {
        return (
            <h1>{this.props.example}</h1>
        )
    }
}

父类呈现子类。父类将prop传递给名为example的子项。在孩子中,您可以通过调用this.props.example

来访问孩子的价值

答案 1 :(得分:2)

您应该渲染一个包装其他每个组件的主要组件,而不是向DOM渲染10次。您可以重用其他组件中的组件并向下传递道具。

答案 2 :(得分:2)

您必须使用包含这两个的另一个组件,并将所选颜色作为其状态进行管理。当ColorPicker获得新值时,容器的状态会更新,而Box会从容器状态中获取它的颜色值。

ColorPicker应该从道具获取颜色值更改时要执行的回调。

var ColorPicker = React.createClass({

render: function() {

return (
    <div>
        <select id="pick-colors" onChange={this.props.onChange}>
            <option value="red">
                Red 
            </option>

            <option value="green">
                Green 
            </option>

            <option value="blue">
                Blue 
            </option>

        </select>

    </div>
    )
}
});

var App = React.createClass({
    getInitialState: function() {
        return {
             selectedColor: '#FFFFFF'
        }    
    },
    onColorPicked: function(e) {
        this.setState({selectedColor: e.target.value })
    },
    render: function() {
        return (
            <div>
              <ColorPicker onChange={this.props.onColorPicked} />
              <Box color={this.state.selectedColor} />
            </div>
        )
    }

}

唯一有状态的组件应该是App。它通过道具将其状态传递给其他组件。

答案 3 :(得分:1)

这种情况下,您需要将状态提升到包含ColorPicker和Box类的父组件。然后,新的父组件将负责管理当前的颜色状态,并处理对其的任何更改。 reactJS docs on lifting state会对您有所帮助。

答案 4 :(得分:1)

  1. 每个应用程序必须调用一次React.render,因为每次调用都意味着为某个新应用程序创建了新的虚拟DOM
  2. 您必须了解虚拟DOM概念,并在其渲染方法
  3. 中的顶级应用程序容器组件中实现您的标记
  4. 在一个纯粹的情况下,就像这个例子一样,你必须通过App组件状态连接所有数据,意味着ColorPicker组件在更改颜色时将其存储在App状态,从中更新Box组件的路径由更改的值更新,但是如果你开发更复杂的应用程序,您必须使用redux或flux概念组织数据存储,这也是在同一页面上的多个应用程序之间交换数据的正确方法
  5. 所以,here正确的代码,实现你的样本

答案 5 :(得分:1)

你可以做这样的事情

var ColorPicker = React.createClass({
 getInitialState: function() {
  return {color: 'white'}
 },
 handleChange: function(e) {
  var newColor = e.target.value;
  this.setState({color: newColor})
 },

 render: function() {

  return (
   <div>
     <select id="pick-colors" onChange={this.handleChange}>
      <option value="red">Red</option>
      <option value="green">Green</option>
      <option value="blue">Blue</option>
     </select>
    <Box color={this.state.color} />
    <Box color={this.state.color} />
    <Box color={this.state.color} />
  </div>
 )
}
});

//contains the boxes that will eventually change color
var Box = React.createClass({
 render: function() {
  return (
   <div >
    <div className='box' style={{background:this.props.color}}> 
    </div>
   </div>
  );
 }
});

ReactDOM.render(<ColorPicker />, document.getElementById('pick_color'));

而不是多次渲染框或使用@ gesuwall的建议。我认为他的方式是更有效的方式。

答案 6 :(得分:0)

将属性从父级传递给子级时,需要使用componentDidUpdate()方法进行收集和使用。否则,这些属性可能尚未初始化,并导致子组件中的值为空。我从上面修改了代码,以包括componentDidUpdate()方法。

class Parent extends React.Component {
    render() {
        return (
            <Child bandName="foo fighters" />
        )
    }
}

class Child extends React.Component {

    //For props, you use componentDidUpdate
    componentDidUpdate(prevProps){

      //You must have an if check, or loop forever
      if(this.props.bandName !== this.prevProps.bandName){}
         //do something like make an API call
         //perhaps set this on state for display
      }
    }

    render() {
        return (
            <h1>{this.props.bandName}</h1>
        )
    }
}