我刚刚开始使用 React,根据我的情况调整井字游戏教程。 我正在尝试单击孙组件以更改祖父组件的状态。代码如下:
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 } />
);
};
我收到一个类型错误:无法从这一行读取未定义的属性“状态”:
handleClick(i) {
const fields = this.state.fields.slice();
答案 0 :(得分:1)
this
类的 App
未绑定到 handleClick
函数。这是 TypeError: Cannot read property 'state' of undefined
错误的原因。fields[i].show = true;
会改变状态中的对象引用。fields
或 onClick
道具传递给 Preview
。onClick
中未正确调用 Preview
回调。将 this
绑定到处理程序或转换为箭头函数使其自动绑定。
constructor(props){
...
this.handleClick = this.handleClick.bind(this);
}
或
handleClick = (i) => { ..... };
不要改变状态。浅拷贝状态然后更新属性。
handleClick = (id) => {
this.setState(prevState => ({
fields: prevState.fields.map((field) => {
return field.id === id ? {
...field,
show: true,
} : field;
}),
}));
};
将 fields
和 handleClick
作为 onClick
传递给 Preview
。
render() {
return (
<Preview
fields={this.state.fields}
onClick={this.handleClick}
/>
);
}
使用 id 正确调用 props.onClick
。
{props.fields.map((field) => (
<Field
data={field}
key={field.id}
onClick={() => props.onClick(field.id)}
/>
))}
答案 1 :(得分:0)
我已经添加了一些解释,请查看评论
// [...]
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 } />
);
};