再次获取还是设置状态? -反应,还原

时间:2018-06-27 19:39:50

标签: javascript reactjs redux react-redux

这是一个总是使我困惑的问题,所以我决定要问你。我的意思是我有一个节点服务器,在后端有一个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个嵌套循环才能找到目标元素。

我知道这个问题没有“黄金答案”,但是我想知道何时使用它。这些方法(在性能方面)之间有很大差异吗?

1 个答案:

答案 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
  }
};