Действие не определено или невидимо, даже если оно написано правильно - PullRequest
0 голосов
/ 10 января 2020

Я должен использовать useDispatch () для своих кнопок-переключателей, поэтому мне нужно отвести их от реакции на состояние редукции. Я следовал руководству по основам Redux и думаю, что сделал это правильно, но когда я пытаюсь хотя бы использоватьSelector для отображения избыточного состояния кнопки, он ничего не показывает.

Так вот мой код:

// types. js в папке действий

   export const TOGGLE = "TOGGLE";

// buttonActions в папке действий

 export const toggle = () => {
return {
type: 'TOGGLE'
};
};

// buttonReducer в папке редукторов

const buttonReducer = (state = true, action) => {
 switch(action.type) {
  case 'TOGGLE':
    return !state;
  default:
    return state;
};
};

 export default buttonReducer;

А кнопка Reducer импортируется в combReducers, который go хранить.

Код компонента:

import React, { useState, useEffect } from 'react'
import isloff from './mainpage_imgs/isloff.png'
import islon from './mainpage_imgs/islon.png'
import PropTypes from "prop-types";
import { connect, useDispatch, useSelector } from "react-redux";
import { toggle } from '../../actions/buttonActions'

  const Islbutton = props => {

const [open, setOpen] = useState(true);
const [role, setRole] = useState('');



useEffect(() => {
  if (props.auth.user) 
  { 
    setRole(props.auth.user.role);
  }
}, []);

const test = useSelector(state => state.button);

 const checkRole = (role) => {
  if (role === 'Menager' || role === 'Technolog')
   {
      return true }
    else 
    {
      return false
    };
}

const toggleImage = () => {
if(checkRole(role)) {
setOpen(!open)
};
}

     const getImageName = () => open ? 'islOnn' : 'islOfff'

const dispatch = useDispatch();

            return(

              <div>

                <img style={islplace} src={open ? islon : isloff }          
onClick={()=> dispatch(toggle())} />

              </div>
            );
    }


Islbutton.propTypes = {
button: PropTypes.func.isRequired,
auth: PropTypes.obj.isRequired
};

const mapStateToProps = state => ({
button: state.button,
auth: state.auth
});

export default connect(mapStateToProps, {}), (Islbutton);

1 Ответ

1 голос
/ 10 января 2020

На основании ваших последних комментариев и моего понимания вашего варианта использования я могу предложить следующий подход:

//dependencies
const { render } = ReactDOM,
      { createStore } = Redux,
      { connect, Provider } = ReactRedux
      
//action creators
const SET_ROLE = 'SET_ROLE',
      MANAGER_APPROVED = 'MANAGER_APPROVED',
      setRole = role => ({type:SET_ROLE, role}),
      mngAppr = () => ({type:MANAGER_APPROVED})

//initial state, reducer, store
const initialState = {role:'Technolog', approved:false},
      appReducer = (state=initialState, action) => {
        switch(action.type){
          case SET_ROLE : {
            const {role} = state,
                  {role: newRole} = action
            return {...state, role: newRole}
          }
          case MANAGER_APPROVED : {
            const {approved} = state
            return {...state, approved: !approved}
          }
          default: return state
        }
      },
      store = createStore(appReducer)

//ui component to emulate toggling roles
const SwitchRoles = ({currentRole, switchRole}) => (
    <div>
      <label><input type="radio" name="role" value="Manager" onChange={e => switchRole(e.target.value)} />Manager</label>
      <label><input type="radio" name="role" value="Technolog"  onChange={e => switchRole(e.target.value)} />Technolog</label>
    </div>
)

//connect radio buttons click to togling roles action
const mapDispatch = dispatch => ({switchRole: role => dispatch(setRole(role))}),
      SwitchRolesContainer = connect(null,mapDispatch)(SwitchRoles)

//ui component to toggle 'approved' within global state      
const ToggleApprove = ({onApprove,isManager}) => (
  <button onClick={onApprove} disabled={!isManager}>Toggle</button>
)

//connect onToggle handler to dispatching 'toggle' action
const mapStateToProps = ({role}) => ({isManager: role == 'Manager'}),
      mapDispatchToProps = dispatch => ({onApprove: () => dispatch(mngAppr())}),
      ToggleApproveContainer = connect(mapStateToProps, mapDispatchToProps)(ToggleApprove)
      
//ui component to display current state of 'open'       
const IsApproved = ({isApproved}) => <div>{isApproved ? 'Approved by manager' : 'Not approved by manager'}</div>

//attach isOpen prop to global 'open' variable
const mapState = ({approved}) => ({isApproved: approved}),
      IsApprovedContainer = connect(mapState)(IsApproved)
      
//render the app
render (
  <Provider store={store}>
    <SwitchRolesContainer />
    <IsApprovedContainer />
    <ToggleApproveContainer />
  </Provider>,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.1.3/react-redux.min.js"></script><div id="root"></div>

Надеемся, что это дает представление о переключении глобальных переменных и отображении их значений в состояние локальных компонентов.

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