Redux从当前页面传递/刷新状态

时间:2018-05-25 00:56:50

标签: reactjs redux

我有一个反应应用程序(repo),我想使用redux来普遍存储状态,因此root应用程序可以访问它。

例如:一个页面有一个填充页面的GET API调用。这很好,所有,但我很困惑如何做几件事。

  1. 如何在redux操作中使用变量,给动作说出模型的ID并让它返回模型(API返回json)。
  2. 我怎样才能传递该状态,以便更高阶的组件(例如基础App.js)可以访问该状态,以便我可以在导航中使用当前页面中的变量。
  3. 更新redux状态的最佳方式/时间是什么/何时,以便使用redux状态在任何地方反映更改?
  4. 具体来说(在这个项目中):如果你在localhost/spells/X上,X是模型ID,我怎样才能将状态从该页面的容器组件(在本例中为LayoutSpellView)传递到MaterialUIApp

    index.js
      |--App.js
         |--MaterialUiApp
            |--Router
               |--LayoutSpellView (pass state up to MaterialUiApp)
    

2 个答案:

答案 0 :(得分:4)

使用Redux,您不会向上或向下传递状态。您可以使用您的操作创建者和缩减器更新全局状态。无论您需要到达哪个州,都可以将组件连接到州并使用它。你有一个商店,它包括一个全球国家。该全球状态可能包含多个不同的状态。

  1. 您可以使用有效负载或任何其他名称,变量与您的操作创建者。在你的reducer中,你可以使用action.payload,action.id等获得那些

  2. 正如我在第一段中所解释的那样,您可以在需要时更新您的状态。之后,您可以将任何组件连接到您所在的州。

  3. 没有最好的时间或最好的方法。这取决于您的代码和应用程​​序逻辑。

  4. 当然有一些最佳实践,但我们不能这么广泛地谈论它们。在您参与Redux之后,您将看到其中的一些。例如,我说“我们不会使用Redux向上或向下传递状态”。这是正确的,但有时为了避免在我们使用容器应用程序的组件周围有这么多connect,将该应用程序连接到存储(实际上通过商店到达状态),然后将相关的状态部分传递给相关组件。

    我建议使用Redux自己的文档作为起点:https://redux.js.org/

答案 1 :(得分:0)

为了帮助您查看数据流,以下是一切如何联系在一起的草图。在下面的示例代码中,这是数据流:

  1. 点击"加载评论"按钮使用参数userId调度thunk。 (thunk是异步操作。)

  2. thunk使用userId进行异步调用,then使用收到的注释作为其有效负载调度操作setComments(comments)

  3. Comments reducer捕获该操作并使用comments数组更新Redux状态。

  4. 在mapStateToProps中更新comments的容器

  5. 组件收到更新后的comments,并在<ul>

  6. 中显示
        // actions.js
        export const SET_COMMENTS = "MyApp/setComments";
        export const setComments = comments => ({
          type: SET_COMMENTS,
          payload: comments
        });
    
        // thunks.js
        import { setComments } from './actions';
        export const getCommentsAsync = id => dispatch => {
          return axios
            .get(`http://localhost:5000/comments/${id}`)
            .then(comments => dispatch(setComments(comments)));
        };
    
        // reducer.js
        import { SET_COMMENTS } from './actions';
        const initialState = {
          comments: []
        };
    
        export const reducer = (state = initialState, action) => {
          switch (action.type) {
            case SET_COMMENTS:
              const comments = action.payload;
              return {
                ...state,
                comments
              };
            default:
              return state;
          }
        };
    
        // components.js
        export default function CommentsList({ comments, loadComments, userId }) {
          return (
            <div>
              <ul>
                {comments.map(comment => <li key={comment.id}>{comment.body}</li>)}
              </ul>
              <button onClick={() => loadComments(userId)}>Load Comments</button>
            </div>
          );
        }
    
        // containers.js
        import { connect } from "react-redux";
        import { getCommentsAsync } from "./thunks";
        import CommentsList from "./components";
    
        mapStateToProps = state => ({
          comments: state.comments,
          userId: state.user.id
        });
    
        mapDispatchToProps = {
          loadComments: getCommentsAsync
        };
    
        export default connect(mapStateToProps, mapDispatchToProps)(CommentsList);