如何在 React Redux 中访问存储状态?

IT技术 javascript asynchronous reactjs redux react-redux
2021-04-20 07:50:14

我只是在制作一个简单的应用程序来学习与 redux 的异步。我已经让一切正常,现在我只想在网页上显示实际状态。现在,我如何在渲染方法中实际访问商店的状态?

这是我的代码(所有内容都在一页中,因为我只是在学习):

const initialState = {
        fetching: false,
        fetched: false,
        items: [],
        error: null
    }

const reducer = (state=initialState, action) => {
    switch (action.type) {
        case "REQUEST_PENDING": {
            return {...state, fetching: true};
        }
        case "REQUEST_FULFILLED": {
            return {
                ...state,
                fetching: false,
                fetched: true,
                items: action.payload
            }
        }
        case "REQUEST_REJECTED": {
            return {...state, fetching: false, error: action.payload}   
        }
        default: 
            return state;
    }
};

const middleware = applyMiddleware(promise(), thunk, logger());
const store = createStore(reducer, middleware);

store.dispatch({
    type: "REQUEST",
    payload: fetch('http://localhost:8000/list').then((res)=>res.json())
});

store.dispatch({
    type: "REQUEST",
    payload: fetch('http://localhost:8000/list').then((res)=>res.json())
});

render(
    <Provider store={store}>
        <div>
            { this.props.items.map((item) => <p> {item.title} </p> )}
        </div>
    </Provider>,
    document.getElementById('app')
);

因此,在 state 的 render 方法中,我想列出item.title商店中的所有内容

谢谢

6个回答

您应该创建单独的组件,它将监听状态更改并在每次状态更改时进行更新:

import store from '../reducers/store';

class Items extends Component {
  constructor(props) {
    super(props);

    this.state = {
      items: [],
    };

    store.subscribe(() => {
      // When state will be updated(in our case, when items will be fetched), 
      // we will update local component state and force component to rerender 
      // with new data.

      this.setState({
        items: store.getState().items;
      });
    });
  }

  render() {
    return (
      <div>
        {this.state.items.map((item) => <p> {item.title} </p> )}
      </div>
    );
  }
};

render(<Items />, document.getElementById('app'));
@BangDao 我们可以假设,我们是从外部文件导入它。store变量 - 它是 redux 存储实例。
2021-05-29 07:50:14
@BangDaostore为了清楚起见,您应该包括导入。
2021-06-05 07:50:14
import store from '../reducers/store';. 并且store.js会包含const createStoreWithMiddleware = applyMiddleware(thunkMiddleware,promise)(createStore); export default createStoreWithMiddleware(reducers);
2021-06-09 07:50:14
@1ven 我们如何在store这里定义变量?
2021-06-15 07:50:14
ReferenceError 找不到变量:存储
2021-06-21 07:50:14

进口connectreact-redux并用它来的组件与连接状态connect(mapStates,mapDispatch)(component)

import React from "react";
import { connect } from "react-redux";


const MyComponent = (props) => {
    return (
      <div>
        <h1>{props.title}</h1>
      </div>
    );
  }
}

最后,您需要将状态映射到props以访问它们 this.props

const mapStateToProps = state => {
  return {
    title: state.title
  };
};
export default connect(mapStateToProps)(MyComponent);

只有您映射的州才能通过 props

看看这个答案:https : //stackoverflow.com/a/36214059/4040563

进一步阅读:https : //medium.com/@atomarranger/redux-mapstatetoprops-and-mapdispatchtoprops-shorthand-67d6cd78f132

注意:这样,如果不调用操作(在 中定义mapDispatchToProps,就无法访​​问道具如果您试图在不分派另一个获取周期的情况下获取商店中已有的内容,那么您将不得不使用subscribegetStatestore.
2021-06-01 07:50:14

您需要使用Store.getState()来获取商店的当前状态。

有关getState()观看短片的更多信息

类型错误:未定义不是对象(评估“_redux.Store.getState”)
2021-05-22 07:50:14
所以我只是this.props.items改为store.getState().items当我这样做时,它没有输出item.title.
2021-05-27 07:50:14
@Parkicism 看起来您没有为组件进行初始渲染。我强烈建议您观看本课程:egghead.io/courses/getting-started-with-redux
2021-06-04 07:50:14
我已经let store = createStore(todoApp);进去了index.js,我想进入store内部App.js- 它的方式是什么?
2021-06-16 07:50:14
@Parkicism 这不显示项目,因为当应用程序第一次渲染时,还没有收到来自服务器的响应,您需要订阅商店,每次商店更改时更新组件。
2021-06-18 07:50:14

所有的答案都来自前钩时代。您应该使用 useSelector-hook 从 redux 获取状态。

在您的 redux-reducer 文件或您可以轻松导入的地方:

import { useSelector } from 'react-redux'

export function useEmployees() {
  return useSelector((state) => state.employees)
}

在您的应用程序代码中:

const { employees } = useEmployees()

有关 redux-hooks 的更多信息:https ://react-redux.js.org/api/hooks以实现此目标。

@Yogi,您可以完全使用它而无需额外的挂钩。我个人更喜欢只在 Redux 文件夹下保留 Redux 特定的 useSelector。次要原因是我发现 useEmployees 更具表现力
2021-05-30 07:50:14
这个钩子会监听商店的变化吗?每次 store 改变时,它会更新局部变量并重新渲染组件吗?
2021-06-04 07:50:14
@IbrahimFarooq,是的,确实如此。它的功能就像一个传递的道具。
2021-06-12 07:50:14
为什么我们需要在 useSelector() 上使用另一个钩子? const employees = useSelector( state => state.employees)
2021-06-13 07:50:14
@IlmariKumpula 谢谢你的解释!这是在 redux 文件夹下保留 useSelector 调用函数的好格式。
2021-06-14 07:50:14

你想做的不仅仅是getState您想对商店中的变化做出react。

如果你没有使用 react-redux,你可以这样做:

function rerender() {
    const state = store.getState();
    render(
        <div>
            { state.items.map((item) => <p> {item.title} </p> )}
        </div>,
        document.getElementById('app')
    );
}

// subscribe to store
store.subscribe(rerender);

// do initial render
rerender();

// dispatch more actions and view will update

但更好的是使用 react-redux。在这种情况下,您可以像提到的那样使用 Provider,然后使用connect将您的组件连接到商店。

op 专门询问 React-Redux。为什么要为请求以外的东西提供解决方案?
2021-05-25 07:50:14
ReferenceError 找不到变量:存储
2021-06-13 07:50:14