更新 Redux 存储时反应组件不重新渲染

Posted

技术标签:

【中文标题】更新 Redux 存储时反应组件不重新渲染【英文标题】:React component not re-rendering when updating Redux store 【发布时间】:2018-08-02 07:42:06 【问题描述】:

我正在尝试创建一个切换来收藏卡片组件,以便它在我的 Favorites.js 组件中呈现。我正在使用 Redux 来存储状态,但是当我调度一个动作以从存储中添加或删除它们时,组件不会呈现。我想我正在改变数组的状态。

这里是减速器:

 export function rootReducer(state = [], action) 


      switch(action.type) 
        case 'ADD_FAVORITE':
        return state.concat(action.data);
        case 'SUB_FAVORITE':
        return state.filter(state => state.name !== action.data.name);
        default:
          return state;
      
    

我尝试使用 Object.assign 创建一个新数组,但由于传递到我的状态的数据本身在一个数组中,我不能使用 store.getState() 将它们映射到我的组件中。数组嵌套在自身内部。

这是我正在运行 onClick 以调度操作的函数:

toggleFavorites(e) 
    if
    (store.getState().includes(this.props.data))
  
    console.log(this.props.data.name + ' removed from favorites');
    store.dispatch(type: 'SUB_FAVORITE', data: this.props.data);

  
    else

    console.log(this.props.data.name + ' added to favorites');
    store.dispatch(type: 'ADD_FAVORITE', data: this.props.data);
  

This.props.data 是通过引用 JSON 对象中的数组并将其映射到我的卡片组件中传递的

这是我正在渲染的卡片组件:

render() 
    let name, description, url , screenshot = this.props.data;
    return (
      <div className="cardComponent">
        <div className="CTA-container">
          <div className="CTA-wrapper">
            <div onClick=() => this.toggleFavorites(this.props.data)className="CTA-icon"><IconComponent icon="favorite"/></div>
            <a href=url className="CTA-icon" target="_blank"><IconComponent icon="link"/></a>
        </div>
      </div>
      <img src=screenshot  className="cardComponent_img"/>
      <a href=url className="cardComponent_name" target="_blank">name</a>
      <p className="cardComponent_description">description</p>

      </div>

我将这些卡片组件渲染到 Favorites.js 组件中,如下所示:

class Favorites extends Component 

  constructor(props) 
    super(props);
   
    render() 

        let cardComps = store.getState().map(data => 
          return (
            <CardComponent data = data />
          )
        )

        return (

          <div>

          <div className="array-component">cardComps</div>

export default Favorites;

我对 React 和 Redux 还很陌生,所以我不确定我在设置组件时是否做错了什么。我只需要在用户从他们的收藏夹中添加或删除组件时重新渲染它。

【问题讨论】:

【参考方案1】:

Redux 会比较更新状态的参考,并据此决定是否更新组件。

Array#concatArray#filter返回具有相同引用元素的新数组。因此,状态比较返回 false 并且不进行渲染

假设action.data 是一个一维数组。 这应该可以。

switch(action.type) 
    case 'ADD_FAVORITE':
       return [...state,action.data];
    case 'SUB_FAVORITE':
       return [...state.filter(state => state.name !== action.data.name)]
    default:
       return state;
 

【讨论】:

【参考方案2】:

你还需要使用 react-redux 库的 connect 方法来监听 store 更新。作为参考,我已经包含了代码。

In Reducer

switch(action.type) 
    case 'ADD_FAVORITE':
        return [...state,action.data];
    case 'SUB_FAVORITE':
        return [...state.filter(state => state.name !== action.data.name)]
    default:
        return state;

In Favorites.js Components

import  connect  from 'react-redux';

class Favorites extends Component 
    constructor(props) 
        super(props);
        this.state = 
            storeData: []
        
    
    componentWillReceiveProps(nextProps)
        if(nextProps.storeData !== this.state.storeData)
            this.setState(
                storeData: nextProps.storeData
            )
        
    
    render() 
        const  storeData  = this.state;
        let cardComps = storeData.map(data => 
            return <CardComponent data = data />;
        )
        return (
            <div className="array-component">cardComps</div>;
        );
    


const mapStateToProps = state => 
    return 
        storeData: state
    ;
;

const connectedFavorites = connect(mapStateToProps)(Favorites);

export default connectedFavorites;

【讨论】:

谢谢! storeData.map 没有为我呈现。不知何故,当我将其更改为 store.getState().map 时,它就可以工作了!我试图将 CardComponent 连接到收藏夹,但似乎我应该反过来做。

以上是关于更新 Redux 存储时反应组件不重新渲染的主要内容,如果未能解决你的问题,请参考以下文章

将新的商店状态放入道具后,反应不会重新渲染

在 redux 中调度存储变量时,React 组件不会重新渲染

如何在 redux 状态更新时自动刷新组件

反应父组件不重新渲染

对道具更改做出反应重新渲染

如何防止扩展的 React-Table 行在重新渲染时折叠?