将dom操作放入redux reducer的坏主意?

问题描述

我有几个使用相同的reducer的动作,而不是在每个动作中都进行dom操作,我想将其添加到共享的reducer中一次。我知道减速器是纯粹的(返回的数据仍然是纯正的),但这是某种反模式还是可以接受的策略?

 case APPEND_POSTS:
      !payload.length &&
        document.getElementById('posts-cont').classList.add('no-more-posts'); // this 
      const total = state.posts.length + payload.length;
      const limit = total > posts_to_keep_limit ? 50 : 0;
      return {
        ...state,posts: [...state.posts.slice(limit),...payload],loading: false,};
    ```

解决方法

Redux Action

 case APPEND_POSTS:
      // you don't need to use below code.
      // !payload.length && document.getElementById('posts-cont').classList.add('no-more-posts'); // this 
      const total = state.posts.length + payload.length;
      const limit = total > posts_to_keep_limit ? 50 : 0;
      return {
        ...state,posts: [...state.posts.slice(limit),...payload],nomore: true,loading: false,};

您的组件。

function YourComp(props){
  const state = useSelector(...); 

  return ( <div id="posts-cont" className={state.nomore ? 'no-more-posts' : ''} > {...}</div>

 
} 
,

我知道reducer是纯函数(返回的数据仍然是纯函数),但这是某种反模式还是可接受的策略?

返回的数据是纯数据,但是您已经以DOM突变的形式引入了副作用。因此,该减速器不是纯净的。

这确实是一种反模式,因为现在,渲染posts-cont个项目的组件与该化简器之间存在不可见的耦合。它使您的代码库更难以阅读和调试。

,

jinongun的建议是好的:让组件的className使用选择器从商店的状态派生其值。一般问题的答案

我有几个使用相同的reducer的动作,而不是 在每个操作中都有一个dom操作,我只想添加它 一次进入我的共享reduce。

永远不要在化简器中进行DOM操作。 永远不要进行任何非纯计算的操作。

但是您可以创建一个总是会产生副作用的动作创建者(使用Redux-Thunk):

function appendPosts(payload) {
  return dispatch => {
    mySideEffect()

    dispatch({
      type: APPEND_POSTS,payload
    })
  }
}

function action1(params) {
  return dispatch => {
    dispatch({
      type: ACTION1,payload: params
    })    

    dispatch(appendPosts(params))
  }
}

function action2(params) {
  return dispatch => {
    dispatch({
      type: ACTION2,payload: params
    })    

    dispatch(appendPosts(params))
  }
}

// etc

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...