如何改变孩子的道具?

时间:2016-08-25 15:53:18

标签: javascript reactjs

我是React的新手。这可能是一个noob问题。

我想更改" filteredFields"当用户单击复选框时,我的MeteorGriddle组件的prop。我的JSX:

const bookingsPage = () => {
    let filteredFields = ['userName'];
    const handleClick = (e) => {
        if (e.target.checked) {
            filteredFields = ['userEmail'];

            // How to propagate this change to the MeteorGriddle?
        }
    }

    return (
        <div>
            <label><input type="checkbox" defaultChecked="true" value="userEmail" onClick={handleClick}/>Email</label>

            <MeteorGriddle filteredFields={filteredFields}/>
        </div>
    );
};

3 个答案:

答案 0 :(得分:2)

我看到了解决问题的两种方法。

执行此操作的第一个简单方法:

将bookingsPage组件转换为有状态的组件而不是功能组件, 然后你就可以在其中创建状态,然后在事件上改变状态并将其传递给MeteorGriddle组件。

所以代码是:

class bookingsPage extends React.Component {
    getInitialState = () => {
      filteredFields: []
    }

    handleClick = (e) => {
        if (e.target.checked) {
            const newFilteredFields = 
              [ ...this.state.filteredFields ].push('userEmail');
            this.setState({ filteredFields: newFilteredFields });
        }
    }

    render() {
    return (
        <div>
            <label>
              <input
                type="checkbox" 
                defaultChecked="true" 
                value="userEmail" 
                onClick={this.handleClick}
              />
              Email
            </label>

            <MeteorGriddle 
              filteredFields={this.state.filteredFields}
            />
        </div>
    );
  }
};

第二种也是更难的方法:

看看Redux。它解决了React中的数据流问题。 基本概念是当你选中复选框时,你将一个动作分配到reducer(也就是你的反应组件的全局数据存储),然后GriddleComponent接收你的应用程序的新状态,里面有新的数据告诉他复选框被检查。 / p>

说你是否希望我为你写一个基于你的例子。

答案 1 :(得分:1)

正如@Maxx所说,你应该使用一个带状态的组件。然后,当你调用setState方法时,它将再次渲染,更新子项的道具。

在你的情况下这应该工作(也使用ES6表示法):

import React from 'react';
import MeteorGriddle from '...whatever path...';

class bookingsPage extends React.Component {

  state = {
    filteredFields: ['userName']
  };

  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    if (e.target.checked) {
      this.setState({
        ...this.state, //This is just a good practice to not overwrite other properties
        filteredFields: ['userEmail']
      });
    }
  }

  render() {
    const { filteredFields } = this.state;

    return(
      <div>
          <label>
            <input type="checkbox" defaultChecked="true" value="userEmail" 
                onChange={this.handleChange}/>Email
          </label>
          <MeteorGriddle filteredFields={filteredFields}/>
      </div>
    );
  }
}

答案 2 :(得分:0)

有很多方法可以实现这一点,您可以尝试使用以下代码,

import React from 'react';

class bookingsPage extends React.Component {

  state = {
    filteredFields: ['userName']
  };

constructor(props) {
 super(props);
}

handleChange(e) {
if (e.target.checked) {
  this.setState({
    filteredFields: ['userEmail']
  });
 }
}
render() {

return(
  <div>
      <label>
        <input type="checkbox" defaultChecked="true" value="userEmail" 
            onChange={this.handleChange.bind(this)}/>Email
      </label>
      <MeteorGriddle filteredFields={this.state.filteredFields}/>
  </div>
  );
}}