Состояние контекста реакции не разделяется между компонентами - PullRequest
0 голосов
/ 18 марта 2020

Я давно использую Redux, но теперь решил опробовать новый ContextAPI.

Я установил его работу с одним компонентом / страницей (используя Next Js), однако состояние не Не распределяются между страницами / компонентами.

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;

Редуктор. 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;

добавить страницу игроков / игроков / добавить (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));

страница лобби игроков / игроки / лобби (страница лобби игроков. 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 (Next Js)

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;

ПРОБЛЕМА:

  • Есть две вкладки open

    1. Добавить игроков
    2. Лобби
  • Добавить нового игрока

    1. Посмотреть этого игрока добавлено на странице «Добавить игроков»

    2. Обратите внимание, что на странице «Лобби» НИЧЕГО не происходит

1 Ответ

0 голосов
/ 19 марта 2020

Ладно, проблема в том, что я пытался " поделиться " контекстным API-интерфейсом между различными открытыми вкладками, по умолчанию это не работает, даже для приставки (пробовал добавлять и сталкивался тот же результат), для redux для этого есть библиотека redux-state-syn c, тем не менее я буду использовать сокеты в будущем, так что это не будет проблемой. Закрыто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...