首页 > 解决方案 > Redux:更新状态后组件未更新

问题描述

我创建了减速器并使用它来更改我的商店的状态。但是正如您在App.js中看到的那样,每当我单击按钮并更新状态时。它更新。我可以在控制台中看到它。但组件不更新。如您所见,我有没有更新的曲目列表。如果我因为组件重新渲染而对代码进行任何更改,我可以看到之后的新状态。为什么状态更新时它不会自动呈现。

行动

import * as actions from './actionTypes'

export const trackAdded = (title, artist, audioSrc, img) => {
    return {
        type: actions.TRACK_ADDED,
        payload: {
            title,
            artist,
            audioSrc,
            img
        }
    }
}

减速器

import * as actions from './actionTypes'

export default function reducer(state = [], action) {
    switch (action.type) {
        case actions.TRACK_ADDED:
            return [
                ...state,
                {
                    title: action.payload.title,
                    artist: action.payload.artist,
                    audioSrc: action.payload.audioSrc,
                    img: action.payload.img
                }
            ]

        default:
            return state
    }
}

应用程序.js

import './App.css';
import store from './store'
import { trackAdded } from './actions'

function App() {
  const add = (title) => {
    store.dispatch(trackAdded(title, "Taylor Swift", "src", "image"))
    console.log(store.getState())
  }
  
  return (
    <div className="App">
      {store.getState().map((track, track_id) => {
        return (
          <li key={track_id}>{track.title}</li>
        )
      })}
      <button onClick={() => { add("Shake It Off") }}>Add Track</button>

    </div>
  );
}

export default App;

标签: javascriptreactjsreduxecmascript-6

解决方案


组件不会更新,因为store.getState()内部<div className="App">只会在组件被调用时运行一次。不存在告诉组件重新运行store.getState(). 如果您希望组件在 store 的状态更改时接收更新,您需要使用react-reduxconnect函数或useSelector挂钩将其连接到 store。

例如,如果使用该connect函数,您可以将 redux 状态映射到 react 组件的 props。因此,如果组件的 props 发生变化,那么组件将对它的 props 变化做出“反应”。redux 的 state 到组件 props 的映射发生在 mapStateToProps 函数中,返回一个tracks映射到组件的 prop。否则,组件没有理由更新。另请注意:在下面的示例中,商店通过Provider组件连接到 React,将商店提供给希望连接到它的子组件。

import { Provider, connect } from 'react-redux'

import './App.css';
import store from './store'
import { trackAdded } from './actions'

function App(props) {
  const add = (title) => {
    store.dispatch(trackAdded(title, "Taylor Swift", "src", "image"))
    console.log(store.getState())
  }
  
  return (
    <Provider store={store}>
      <div className="App">
        {props.tracks.map((track, track_id) => {
          return (
            <li key={track_id}>{track.title}</li>
          )
        })}
        <button onClick={() => { add("Shake It Off") }}>Add Track</button>
      </div>
    </Provider>
  );
}

const mapStateToProps = (state) => {
  const tracks = state
  return { tracks }
}

export default connect(mapStateToProps)(App);

话虽如此,如果你走这connect条路,你可能想在其中添加一个mapDispatchToProps功能,connect这样你就不会到处乱跑了store。您可以在 redux 文档中找到该信息,但这将是另一个问题的答案。


推荐阅读