如何改变一个孩子的道具

How to change props of a child?

本文关键字:孩子 一个 何改变 改变      更新时间:2023-09-26

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

我想在用户单击复选框时更改MeteorGriddle组件的"filteredFields"属性。我的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>
    );
};

我知道有两种方法可以解决你的问题。

第一个简单的方法是:

把你的bookingpage组件变成有状态组件,而不是函数式组件。然后你就可以在它里面创建状态,然后在事件上改变状态,同时把它传递给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分派一个动作(也就是react组件的全局数据存储),然后gridlecomcomponent接收到你的应用程序的新状态,里面有新的数据,告诉他复选框被选中了。

如果你想让我为你写一个基于你的例子

正如@Maxx所说,您应该使用带有state的组件。然后当你调用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>
    );
  }
}

有许多方法可以实现这一点,您可以尝试下面的代码,

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>
  );
}}