这是一个总是使我困惑的问题,所以我决定要问你。我的意思是我有一个节点服务器,在后端有一个SQL数据库,在前端有一个Redux存储。每次安装时,主要组件都会提取,处理响应并将其分发到商店。用户看到的所有内容取决于商店。因此,如果发生更改,它将通过服务器上载到数据库,但是如果此更改发生在主要组件的子组件上,则不会将状态上载到存储中,因为主要组件没有安装。让我展示我的意思:
//main component
componentDidMount(){
fetch('http://localhost:3001/')
.then(res => res.json())
.then(items => {
//items: [1, 2, 3]
this.props.dispatch({
type: 'GET_ITEMS',
items
});
})
.catch(err => console.log(err)))
}
//reducer
const initialState = {
items: []
}
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'GET_ITEMS' :
return{
...state,
items: action.items
}
default:
return state
}
};
//child component
userAddsNewElement = e => {
fetch('http://localhost:3001/addElement', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
newElement: e.target.value //4
})
})
//here, we have a few options:
//we can send the whole `items` array as response from the server
//and dispatch it as in componentDidMount
//we can push the new element to the current state
.catch(err => console.log(err)))
}
上面的代码仅是说明我的意思。显然,第二种解决方案看起来更好,但是在我的代码状态下,我需要遍历3个数组以找到目标元素。但是项目的数量在数据库和状态中都是未知的。如果我从数据库中获取项目,它将使用2张地图进行处理,然后进行排序。如前所述,如果要搜索目标项目,我需要做3个嵌套循环才能找到目标元素。
我知道这个问题没有“黄金答案”,但是我想知道何时使用它。这些方法(在性能方面)之间有很大差异吗?
答案 0 :(得分:1)
您可能想要做的事情是这样的:
您的后端状态和前端状态应该保持一致,但是您不需要从后端请求使状态相同。后端请求通过后,只需根据需要对商店进行更改即可。您的GET_ALL只需要在组件安装上运行一次,这将设置商店的初始状态。之后,您将直接修改商店,也直接修改后端。
componentDidMount(){
fetch('http://localhost:3001/')
.then(res => res.json())
.then(items => {
//items: [1, 2, 3]
this.props.dispatch({
type: 'SET_ITEMS', // you'll need to set your reducer up for this
items
});
})
.catch(err => console.log(err)))
}
//子组件
userAddsNewElement = e => {
fetch('http://localhost:3001/addElement', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
newElement: e.target.value //4
})
})
//here, we have a few options:
//we can send the whole `items` array as response from the server
//and dispatch it as in componentDidMount
//we can push the new element to the current state ** this one **
.then(() => { // if were here that means our post request didnt throw an error
this.props.dispatch({
type: 'ADD_ITEM',
payload: e.target.value
});
})
.catch(err => console.log(err)))
}
,然后在您的减速器中:
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'GET_ITEMS' : // not using this anymore but you may for things later.
return state.items
case 'ADD_ITEM' :
return {
...state,
state.items.concat(action.payload)
}
case 'SET_ITEMS' :
return{
...state,
items: action.items
}
default:
return state
}
};