React Context状态未在组件之间共享

时间:2020-03-18 12:21:10

标签: reactjs redux react-hooks next.js

我已经使用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。看到“大厅”页面上什么都没有发生

1 个答案:

答案 0 :(得分:0)

好的,所以问题是我试图在不同的打开标签之间“ 共享”上下文api状态,默认情况下它不起作用,即使对于redux(尝试将其添加并面临相同的结果),对于redux来说,有一个redux-state-sync库,尽管如此,我将来会使用套接字,所以这不会成为问题。 关闭。