Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在React中将onClick函数传递给孙子组件?_Javascript_Reactjs - Fatal编程技术网

Javascript 如何在React中将onClick函数传递给孙子组件?

Javascript 如何在React中将onClick函数传递给孙子组件?,javascript,reactjs,Javascript,Reactjs,我只是从React开始,为我的案例改编tic-tac-toe教程。 我试图单击孙子组件来更改祖父母组件的状态。代码如下: class App extends React.Component { constructor(props) { super(props); this.state = { fields: [ { id: 1, show: false }, {

我只是从React开始,为我的案例改编tic-tac-toe教程。 我试图单击孙子组件来更改祖父母组件的状态。代码如下:

class App extends React.Component {
  
  constructor(props) {
    super(props);
    this.state = {
      fields: [
        {
          id: 1,
          show: false
        },
        {
          id: 2,
          show: false
        }
      ]
    }
  }

  handleClick(i) {
    const fields = this.state.fields.slice();
    fields[i].show = true;
    this.setState({fields: fields});
  }
  
  render() {return <Preview />}
      
}

const Preview = (props) => {
  
  return (
    <div className="preview">
      {props.fields.map((field) => (
        <Field data={field} key={field.id} onClick={ props.onClick(field.id) }/>
      ))}
    </div>
  );
};

const Field = props => {
  
  return (
    <div className="field" onClick={ props.onClick } />
  );
};

我添加了一些解释,请查看评论

  // [...]

  render() {
    // Here you need to pass "fields" and "handleClick" as props:
    return <Preview fields={this.state.fields} onClickField={this.handleClick} />
  }
      
}

const Preview = (props) => {
  // Here you get the props:
  const { fields, onClickField } = props;

  // Your onclick was a function call instead of just a function
  return (
    <div className="preview">
      {fields.map((field) => (
        <Field 
          data={field}
          key={field.id}
          onClick={() => onClickField(field.id) }
        />
      ))}
    </div>
  );
};

const Field = props => {
  
  return (
    <div className="field" onClick={ props.onClick } />
  );
};
/[…]
render(){
//在这里,您需要将“字段”和“handleClick”作为道具传递:
返回
}
}
常量预览=(道具)=>{
//这里是道具:
const{fields,onClickField}=props;
//您的onclick是一个函数调用,而不仅仅是一个函数
返回(
{fields.map((field)=>(
onClickField(field.id)}
/>
))}
);
};
常量字段=道具=>{
返回(
);
};
问题
  • App
    类的
    这个
    没有绑定到
    handleClick
    函数。这是导致
    TypeError:无法读取未定义的
    错误的属性“state”
  • 您正在更改您的状态对象。切片数组将创建一个新的数组引用,但
    字段[i].show=true在状态中更改对象引用
  • 您不会将
    字段
    onClick
    道具传递到
    预览
  • Preview
    中未正确调用
    onClick
    回调
  • 解决方案
  • 将此绑定到处理程序或转换为箭头函数,以便自动绑定

    constructor(props){
      ...
      this.handleClick = this.handleClick.bind(this);
    }
    

  • 不要改变状态。浅复制状态,然后更新属性

    handleClick = (id) => {
      this.setState(prevState => ({
        fields: prevState.fields.map((field) => {
          return field.id === id ? {
            ...field,
            show: true,
          } : field;
        }),
      }));
    };
    
  • 字段
    handleClick
    作为
    onClick
    传递到
    预览

    render() {
      return (
        <Preview
          fields={this.state.fields}
          onClick={this.handleClick}
        />
      );
    }
    

  • 但是您没有向
    handleClick = (id) => {
      this.setState(prevState => ({
        fields: prevState.fields.map((field) => {
          return field.id === id ? {
            ...field,
            show: true,
          } : field;
        }),
      }));
    };
    
    render() {
      return (
        <Preview
          fields={this.state.fields}
          onClick={this.handleClick}
        />
      );
    }
    
    {props.fields.map((field) => (
      <Field
        data={field}
        key={field.id}
        onClick={() => props.onClick(field.id)}
      />
    ))}