gpt4 book ai didi

javascript - 状态更改后子组件不更新

转载 作者:行者123 更新时间:2023-12-01 00:55:50 24 4
gpt4 key购买 nike

我正在学习 React,并且正在制作一个简单的 ToDoApp。我在应用程序组件的状态下从 JSON 文件设置了一些待办事项数据,并使用这些值填充子组件。我编写了一个方法,每次在复选框元素上触发 onChange 事件时都会调用该方法,并通过更新状态来翻转复选框。问题是这段代码以前工作得很好,但现在不行了。当我更改复选框时,状态会相应更新,但它不会在子元素中更新,我想知道为什么。这是我的代码

App.js

import React from "react";
import TodoItem from "./TodoItem";
import toDoData from "./toDosData";

class App extends React.Component {
constructor() {
super();
this.state = {
toDoData: toDoData
};
this.handleOnChange = this.handleOnChange.bind(this);
}

handleOnChange(key)
{
this.setState(prevState => {
let newState = prevState.toDoData.map(currentData => {
if(currentData.id === key)
currentData.completed = !currentData.completed;
return currentData;
});
return {toDoData: newState};
});
}

render() {
let toDoComponents = this.state.toDoData.map(toDoDatum =>
<TodoItem key={toDoDatum.id} details={{
key: toDoDatum.id,
text: toDoDatum.text,
completed: toDoDatum.completed,
onChange: this.handleOnChange
}} />);
return (
<div>
{toDoComponents}
</div>
);
}
}

export default App;

TodoItem.js

import React from "react";

class TodoItem extends React.Component {

properties = this.props.details;

render() {
return (
<div>
<input type="checkbox" checked={this.properties.completed}
onChange={() => this.properties.onChange(this.properties.key)}
/>
<span>{this.properties.text}</span>
</div>
)
}
}

export default TodoItem;

提前致谢。

最佳答案

为什么需要将 details 属性分配给类中的 properties ?如果您这样做,properties 不会反射(reflect) prop 更改,并且您的子组件将无法看到更新。只需按原样使用 Prop 即可:

render() {
const { details } = this.props;
return (
<div>
<input
type="checkbox"
checked={details.completed}
onChange={() => details.onChange(details.key)}
/>
<span>{details.text}</span>
</div>
);
}
}

此外,由于您在 TodoItem 组件中不使用任何状态或生命周期方法,因此它也可以是一个功能组件。

const TodoItem = ({ details }) => (
<div>
<input
type="checkbox"
checked={details.completed}
onChange={() => details.onChange(details.key)}
/>
<span>{details.text}</span>
</div>
);

还有一件事,为什么不直接将 todo 本身传递给 TodoItem 呢?

<TodoItem
key={toDoDatum.id}
todo={toDoDatum}
onChange={this.handleOnChange}
/>

const TodoItem = ({ todo, onChange }) => (
<div>
<input
type="checkbox"
checked={todo.completed}
onChange={() => onChange(todo.id)}
/>
<span>{todo.text}</span>
</div>
);

这不是更具可读性吗?

评论后更新

const toDoData = [
{ id: 1, text: "foo", completed: false },
{ id: 2, text: "bar", completed: false },
{ id: 3, text: "baz", completed: false }
];

const TodoItem = ({ todo, onChange }) => (
<div>
<input
type="checkbox"
checked={todo.completed}
onChange={() => onChange(todo.id)}
/>
<span>{todo.text}</span>
</div>
);

class App extends React.Component {
constructor() {
super();
this.state = {
toDoData: toDoData
};
this.handleOnChange = this.handleOnChange.bind(this);
}

handleOnChange(key) {
this.setState(prevState => {
let newState = prevState.toDoData.map(currentData => {
if (currentData.id === key)
currentData.completed = !currentData.completed;
return currentData;
});
return { toDoData: newState };
});
}

render() {
let toDoComponents = this.state.toDoData.map(toDoDatum => (
<TodoItem
key={toDoDatum.id}
todo={toDoDatum}
onChange={this.handleOnChange}
/>
));
return <div>{toDoComponents}</div>;
}
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root" />

关于javascript - 状态更改后子组件不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56589261/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com