use*_*621 8 javascript reactjs
我正在构建一个简单的待办事项清单.我有一个用于添加新待办事项列表项的表单,并在其下列出待办事项列表中的所有项目.当我通过表单添加新项目时,我想刷新现有待办事项列表项目的列表.
Items.jsx:
class Items extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
loading: true
};
}
componentDidMount() {
axios.get('/api/v1/items')
.then(response => {
this.setState({ items: response.data, loading: false });
});
console.log('state.items: '+this.state.items);
}
componentDidUpdate() {
axios.get('/api/v1/items')
.then(response => {
this.setState({ items: response.data, loading: false });
});
console.log('componentDidUpdate: '+this.state.items);
}
render() {
return (
<ItemSE.Group>
{
this.state.items.map(item => {
return <Item key={item.id} data={item} />
})
}
</ItemSE.Group>
);
}
}
export default Items
Run Code Online (Sandbox Code Playgroud)
App.jsx:
class App extends Component {
constructor () {
super();
this.state = {
item_msg: ''
}
this.handleInputChange = this.handleInputChange.bind(this);
}
handleSubmit(e){
e.preventDefault();
console.log(this.state.item_msg);
axios.post('/api/v1/items', {
item: this.state.item_msg
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
handleInputChange(e) {
this.setState({ item_msg: e.target.value });
console.log('item_msg: '+this.state.item_msg);
}
render() {
return (
<div className="App">
<MainHeaderr />
<Container>
<NewItemForm
send_form={this.handleSubmit.bind(this)}
onInputChange={this.handleInputChange}
typed={this.state.item_msg} />
<Items />
</Container>
</div>
);
}
}
export default App;
Run Code Online (Sandbox Code Playgroud)
我添加componentDidUpdate
到Items.jsx
文件中 - 当我添加一个新的待办事项列表时,这个新的待办事项确实会立即显示在列表中 - 这很酷.但是,我并不觉得这是最好的做法.当我看到JS控制台时,我看到有数百个componentDidUpdate:
.
那么,将列表刷新到todos的最佳方法是什么?
Den*_*sur 10
这是新移民最具挑战性的部分之一ReactJS
.您不应该在每个级别创建有状态组件.
选择州的共同所有者.在你的情况下,Items
组件不能在没有来自父App
组件的数据的情况下自己改变状态,因此没有理由将状态保持在这个位置.
基本上,你应该在组件中保留items
数组和isLoading
标志App
,然后简单地将其传递给Items
作为道具.
然后,您可以通过在后端添加新项目后重新获取数据来更新列表,或者只是将其添加到列表中.
此外,您应该App
在每次输入更改时更新父级的状态.
有两种方法:
您可以将其保持在NewItemForm
状态,然后将onSubmit作为函数prop传递给父事件处理程序.
只是让它无法控制,并且根本不让它保持状态,父母将采取这个参数event.target.value
.(就像现在一样).
在这两种情况下,它都不会每次都重新呈现您的列表.因此,您应该省略handleInputChange
from App
组件.
例如: App.js
constructor(props) {
super(props);
// Initial state
this.state = {
items: [],
isLoading: false,
}
}
handleSubmit(e){
e.preventDefault();
const { value } = e.target;
this.setState({ isLoading: true });
axios.post('/api/v1/items', {
item: value
})
.then(response => {
// there are several ways - choose ONE of them
// 1. If server returns you the created item
// you can just add this item into the list
this.setState(prevState => {
return {
items: [...prevState.items, response.data],
isLoading: false,
}
});
// 2. But if there are any users who can make changing simultaneously with you
// (if not - just imagine it :) ) - it's better to make re-fetch data from server
axios.get('/api/v1/items')
.then(response => {
this.setState(prevState => ({ items: response.data, isLoading: false });
})
.catch(err => { console.log('Something bad is happened:', err) });
}
Run Code Online (Sandbox Code Playgroud)
最后,只需将数据传递到Items
组件中即可.
render() {
const { items, isLoading } = this.state;
return (
...
<Items items={items} isLoading={isLoading} />
...
)
}
Run Code Online (Sandbox Code Playgroud)
如果您还没有阅读本文,我建议您阅读本文 - https://reactjs.org/docs/thinking-in-react.html.
希望能帮助到你.