【问题标题】:The action is undefined or invisible even if it seems written properly动作是未定义的或不可见的,即使它看起来写得正确
【发布时间】:2020-01-10 14:01:13
【问题描述】:

我必须为我的切换按钮使用 useDispatch(),所以我必须将它们从反应到 redux 状态。我正在关注 Redux 基础教程,我认为我已经正确地做到了,但是当我尝试至少使用选择器来显示 redux 按钮的状态时,它没有显示任何内容。

这是我的代码:

//actions 文件夹中的 types.js

   export const TOGGLE = "TOGGLE";

//actions文件夹中的buttonActions

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

// reducers 文件夹中的 buttonReducer

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

 export default buttonReducer;

并且 buttonReducer 被导入到 combineReducer 中去存储。

组件代码:

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);

【问题讨论】:

  • 这与主要问题有关,因为代码不起作用。当然,我可以向您展示 onClick = { () => useDispatch(toggle) } 及其结果“未定义切换/不是函数”,但如果不显示我所做的代码,它就毫无价值,对吧?
  • 好吧,那我的错。马上修改
  • 感谢您的建议,我会遵循它们,因为它会帮助我改进,但现在它适用于 dispatch(toggle())。我有一个问题要问你,因为发生了一些意想不到的事情。它现在改变了所有按钮的状态。在 React 中,它只适用于一个,每个都有自己的按钮。现在,无论我点击哪一个,它都会改变所有这些的状态。有没有办法为一个按钮制作一个状态并继续?我有 16 个相同的按钮
  • 关于dispatch(toggle()),你是对的(我太兴奋了;)。关于您以后的问题,我不太了解您的应用程序的全貌:这些按钮状态是否取决于其他一些全局状态变量?你甚至需要全局存储这些按钮状态吗?但是,到目前为止,我已经在the answer 中总结了我的建议。如果它完全解决了您的问题,欢迎您投票/接受;)或在该评论部分下的评论部分继续提出进一步的问题。
  • 好的,非常感谢您的回答和建议!

标签: javascript function redux react-redux


【解决方案1】:

根据您最新的 cmets 和我对您的用例的理解,我可能会建议采用以下提炼方法:

//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')
)
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"&gt;&lt;/script&gt;&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"&gt;&lt;/script&gt;&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"&gt;&lt;/script&gt;&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.1.3/react-redux.min.js"&gt;&lt;/script&gt;&lt;div id="root"&gt;&lt;/div&gt;

希望它能让您了解切换全局变量并将它们的值映射到本地组件状态。

【讨论】:

  • 哇,我马上测试它,但我害怕添加角色。这些按钮的全部目的是仅在具有特定角色的用户登录时才启用它们。因此,如果具有 Menager 角色的用户登录,他实际上可以单击更改状态的按钮,从而更改图片。我只是不知道如何向其中添加角色要求
  • 根据我的问题,它看起来像这样:gyazo.com/14a83fc2b687d71ee999027885dad6bb 所有按钮都“被点击”,同时只有一个真正被点击。遗憾的是,根据您的话“您是否需要将它们存储在全球范围内”。即使应用程序关闭,我也必须将每个人的状态推送到本地存储以使它们保存,并且我也必须使用 redux-persist
  • 去试试吧!我会稍微调整一下,因为可能存在“没有登录用户”,即:“角色:”和“角色:korespondent”,但我认为由于您刚刚创建的代码,我将能够做到这一点!该死的,如果那会像我想的那样起作用,那么你将成为我真正的上帝
  • 请问有什么联系方式以防万一吗?
  • 我已经检查了您的建议,效果非常好!我仍然在为这样一个事实而苦恼:如果我点击一个按钮,其余的按钮也会被点击。 (所有按钮都是一个组件)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
相关资源
最近更新 更多