Javascript 反应-什么';在添加新元素后刷新数据列表的最佳做法是什么?
我正在建立一个简单的待办事项列表。我有一个用于添加新todo列表项的表单,它下面列出了todo列表中的所有项。通过表单添加新项时,我希望刷新现有待办事项列表项的列表 Items.jsx:Javascript 反应-什么';在添加新元素后刷新数据列表的最佳做法是什么?,javascript,reactjs,Javascript,Reactjs,我正在建立一个简单的待办事项列表。我有一个用于添加新todo列表项的表单,它下面列出了todo列表中的所有项。通过表单添加新项时,我希望刷新现有待办事项列表项的列表 Items.jsx: class Items extends React.Component { constructor(props) { super(props); this.state = { items: [], loading: tru
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
类项扩展React.Component{
建造师(道具){
超级(道具);
此.state={
项目:[],
加载:正确
};
}
componentDidMount(){
get(“/api/v1/items”)
。然后(响应=>{
this.setState({items:response.data,load:false});
});
console.log('state.items:'+this.state.items);
}
componentDidUpdate(){
get(“/api/v1/items”)
。然后(响应=>{
this.setState({items:response.data,load:false});
});
console.log('componentDidUpdate:'+this.state.items);
}
render(){
返回(
{
this.state.items.map(item=>{
返回
})
}
);
}
}
导出默认项
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;
类应用程序扩展组件{
构造函数(){
超级();
此.state={
项目\u消息:“”
}
this.handleInputChange=this.handleInputChange.bind(this);
}
handleSubmit(e){
e、 预防默认值();
console.log(this.state.item_msg);
axios.post(“/api/v1/items”{
项目:this.state.item_msg
})
.然后(功能(响应){
控制台日志(响应);
})
.catch(函数(错误){
console.log(错误);
});
}
handleInputChange(e){
this.setState({item_msg:e.target.value});
console.log('item_msg:'+this.state.item_msg);
}
render(){
返回(
);
}
}
导出默认应用程序;
我在Items.jsx
文件中添加了componentdiddupdate
——当我添加一个新的todo列表时,这个新的todo确实会立即显示在列表中——这很酷。然而,我并不认为这是最好的做法。
当我查看JS控制台时,我看到有数百个组件didUpdate:
因此,刷新待办事项列表的最佳方法是什么?这是
ReactJS
新手最具挑战性的部分之一。
您不应该在每个级别都创建有状态组件
为状态选择一个公共所有者。在您的情况下,Items
组件无法在没有来自父App
组件的数据的情况下自行更改其状态,因此没有理由将状态保留在此位置
基本上,您应该在App
组件中保留items
数组和isLoading
标志,然后将其作为道具传递到items
然后,您可以在后端添加新项目后通过重新获取数据来更新列表,或者只是将其添加到列表中
此外,您应该在每次输入更改时更新家长的App
状态
有两种方法:
NewItemForm
状态,然后将onSubmit作为函数prop传递给父事件处理程序event.target.value
获取此参数。(现在是这样)App
组件中省略handleInputChange
render() {
const { items, isLoading } = this.state;
return (
...
<Items items={items} isLoading={isLoading} />
...
)
}
例如:
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) });
}
最后,只需将数据传递到项中
render() {
const { items, isLoading } = this.state;
return (
...
<Items items={items} isLoading={isLoading} />
...
)
}
render(){
const{items,isLoading}=this.state;
返回(
...
...
)
}
如果你还没有读过这篇文章,我建议你读一读
希望有帮助。如果没有条件检查,您不应该使用componentDidUpdate,否则它将导致无限循环或重新呈现和API调用,因为componentDidUpdate中的setState可以在应用程序组件中存储项,然后将其传递到项目的道具中
组件-这种方法有点难看,所以很多人使用Redux/Relay来存储全局数据,难道你不能将新项目添加到列表中,而不是获取完整的列表吗?