首页 > 解决方案 > 如何使用钩子在 Redux 中切换 React 组件?

问题描述

我正在尝试使用 redux 切换(显示/隐藏)反应组件,但出现错误:

Error: An error occurred while selecting the store state.

当我通过直接调用访问状态时,此错误消失。

改变这个:

const show = useSelector(state => state.toggle[id]);

对此:

const show = useSelector(state => state.empty);

切换组件

import React from 'react';
import {useSelector} from 'react-redux';


export const Toggle = ({id, children}) => {
  const show = useSelector(state => state.toggles[id]);
  return show ? children : null;
};

减速器

const initialState = {
  empty: false
};

export default (state = initialState, action) => {
  switch (action.type) {
    case 'SHOW':
      return {...state, [action.payload]: true};
    case 'HIDE':
      return {...state, [action.payload]: false};
    default:
      return state;
  }
};

行动

export const showToggle = id => ({type: 'SHOW', payload: id});
export const hideToggle = id => ({type: 'HIDE', payload: id});

子组件

import React from 'react';

export const MyComponent = ({onClick}) => {
  return (
    <div>
      Do something awesome here
      <button onClick={onClick}>Ok</button>
    </div>
  )
};

主要部件

import React from 'react';
import {useDispatch} from 'react-redux';
import {Toggle} from './Toggle';
import {MyComponent} from './MyComponent';
import {showToggle, hideToggle} from './actions';

export const SomeOtherComponent = () => {
  const dispatch = useDispatch();
  const toggleId = 'empty';
  return (
    <div>
            <span>Say something<span>
            <Toggle id={toggleId}>
              <MyComponent onClick={() => dispatch(hideToggle(toggleId))}/>
            </Toggle>
            <button onClick={() => dispatch(showToggle(toggleId))}>Show my component</button>
    </div>
)};

基本上,我想通过 ID 切换组件,因为我想添加更多可以切换的组件。

标签: javascriptreactjsreduxreact-reduxreact-hooks

解决方案


你的减速器不是一个数组,所以它会坏掉。

如果你把你的减速器换成这个,它会起作用吗?

const initialState = [];

export default (state = initialState, action) => {
  switch (action.type) {
    case 'SHOW':
      return {...state, [action.payload]: true};
    case 'HIDE':
      return {...state, [action.payload]: false};
    default:
      return state;
  }
};

和你的切换组件到这个:

import React from 'react';
import {useSelector} from 'react-redux';


export const Toggle = ({id, children}) => {
  const show = useSelector(state => state[id]);
  return show ? children : null;
};

选择:

const initialState = {
  show_list: [],
  // other state keys
};

export default (state = initialState, action) => {
  switch (action.type) {
    case 'SHOW':
      let show_list = state.show_list;
      show_list[action.payload] = true;
      return {...state, show_list};
    case 'HIDE':
      let show_list = state.show_list;
      show_list[action.payload] = false;
      return {...state, show_list};
    default:
      return state;
  }
};

切换组件:

import React from 'react';
import {useSelector} from 'react-redux';


export const Toggle = ({id, children}) => {
  const show = useSelector(state => state.show_list[id]);
  return show ? children : null;
};

推荐阅读