【问题标题】:React Context state not shared between componentsReact Context 状态不在组件之间共享
【发布时间】:2020-03-19 06:02:01
【问题描述】:

我已经使用 Redux 很长时间了,但现在决定尝试新的 ContextAPI。

我让它与一个组件/页面一起工作(使用 NextJs),但是页面/组件之间不共享状态。

store.js

import React, { createContext, useReducer } from 'react';
import reducer from './reducer'


const initialState = {
  players: [],
};

const Store = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <Context.Provider value={[state, dispatch]}>
      {children}
    </Context.Provider>
  )
};

export const Context = createContext(initialState);
export default Store;

reducer.js

const Reducer = (state, action) => {
  switch (action.type) {
    case 'ADD_PLAYER':
      return {
        ...state,
        players: [...state.players, action.payload],
      };
    case 'REMOVE_PLAYER_BY_INDEX':
      const array = state.players;
      if (array) {
        array.splice(action.payload, 1);
      }
      return {
        ...state,
        players: !array ? [] : array,
      };
    default:
      return state;
  }
};

export default Reducer;

添加玩家页面/players/add (addplayerspage.js)

import React, { useContext } from 'react';
import map from 'lodash/map';
import isEqual from 'lodash/isEqual';
import { Context } from '../../../context';

const PlayerCreatePage = () => {
  const [_, dispatch] = useContext(Context);
  const handleAddPlayer = () => {
    dispatch({ type: 'ADD_PLAYER', payload: Math.random() });
  };
  const handleRemovePlayerByIndex = (index) => {
    dispatch({ type: 'REMOVE_PLAYER_BY_INDEX', payload: index });
  };
  return (
    <div className="layout">
      <div>
        <Context.Consumer>
          {([state]) => {
            const { players } = state;
            return map(players, (p, i) => <div
              key={i}
              onClick={() => handleRemovePlayerByIndex(i)}
            >
              {p}
            </div>
            )
          }}
        </Context.Consumer>
      </div>
      <button onClick={() => handleAddPlayer()}>Add new</button>
    </div>
  );
};

export default React.memo(PlayerCreatePage, (prev, next) => isEqual(prev, next));

大厅玩家页面/players/lobby (lobbyplayerspage.js)

import React, { useContext } from 'react';
import map from 'lodash/map';
import { Context } from '../../../context';

const PlayersLobbyPage = () => {
  const [state, _] = useContext(Context);
  return (
    <div>
      <div>
        {map(state.players, (p, i) => <div
          key={i}
        >
          {p}
        </div>
        )}
      </div>
    </div>
  );
};

export default PlayersLobbyPage;

_app.js (NextJs)

import App, { Container } from 'next/app';
import '../styles/main.css';
import Store from '../context';

class MyApp extends App {

  render() {
    const { Component, pageProps } = this.props;
    return (
      <Container>
        <Store>
          <Component {...pageProps} />
        </Store>
      </Container>
    );
  }
}

export default MyApp;

问题:

  • 打开两个标签

    1. 添加玩家
    2. 大堂
  • 添加新玩家

    1. 在“添加播放器”页面上查看播放器添加

    2.看到“大厅”页面上没有任何反应

【问题讨论】:

    标签: reactjs redux react-hooks next.js


    【解决方案1】:

    好的,所以问题是我试图在不同的打开选项卡之间“共享”上下文 api 状态,默认情况下它不会那样工作,即使对于 redux(尝试添加它并面临相同的结果),对于 redux 有一个 redux-state-sync 库,但是我将来会使用套接字,所以这不会是一个问题。 关闭。

    【讨论】:

      猜你喜欢
      • 2019-01-31
      • 2020-08-07
      • 1970-01-01
      • 2019-02-18
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-26
      相关资源
      最近更新 更多