按钮属性在状态更改时未更新

时间:2020-10-03 02:17:01

标签: reactjs react-redux

我有一个按钮,它根据映射的状态变量保持禁用状态。加载页面后可以使用,但是经过处理后,状态会更改,但是Button保持启用状态。

国家应该这样转变

loading: false -> button disabled: true
when button is clicked:
    loading: true -> button disabled: true
when processing finishes:
    loading: false -> button disabled: false

加载状态已更改,但是禁用属性只是第一次更改。

Page.jsx(为简单起见,仅提供一些摘要)

  const [disabled, setDisabled] = useState(true);
  const { loading } = useSelector(state => state.spreadsheet);

  const importData = () => {
    importOperations.createRows(rows, dispatch);
  };

 return (
    <>
          <Button
            variant="contained"
            color="primary"
            onClick={importData}
            className={classes.spacing}
            disabled={disabled || loading}
          >
            Import
          </Button>
    </>
  );

importOperations.js

export const createRows = async (rows, dispatch) => {
  dispatch(importActions.setLoading(true));
  // ......
  dispatch(importActions.setLoading(false)); // this step is correctly executed
};

importReducer.js

export const INITIAL_STATE = {
  messagesLog: [],
  loading: false
};

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case spreadsheetActions.SET_LOADING:
      return { ...state, loading: action.payload };
    default:
      return state;
  }
};

您对为什么按钮没有变回禁用状态有任何建议吗?

1 个答案:

答案 0 :(得分:1)

我本来要评论的,请您先澄清以下内容,但它不会让我发表评论,所以我不得不在这里问您:

我认为您提到的逻辑可能存在问题。但是我可能是错的,因此在尝试回答您的问题之前,我先在这里评论。

  • 您说过您想要以下内容,但该方法不起作用,因为如果加载为false,则禁用按钮为true。如果该按钮被禁用,则无法单击它。
  • 您说过,单击按钮时,您希望加载为true。很好,但是您希望禁用按钮为假??您要让人们在按钮加载时单击它吗?
loading: false -> button disabled: true
when button is clicked:
    loading: true -> button disabled: false
when processing finishes:
    loading: false -> button disabled: true
  • 无论如何,我在下面整理了一些有用的代码来匹配您的要求。一旦您确认您提到的逻辑是否正确,我将很乐意为您提供进一步的帮助。

您可以尝试以下方法吗?这是我最好的组合,可以在某种程度上模仿您的代码

import React, { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  const [disabledState, setDisabledState] = useState(false);
  const [loading, setLoading] = useState(false);

  // sets loading to true when clicked, and 
  const importData = () => {
    setLoading((loading) => !loading);

    setTimeout(() => {
      setLoading((loading) => !loading);
    }, 1000);
  };

  // set loading to false initially when component mounts
  useEffect(()=> {
    setLoading(true)
  },[])

  // I would set disabled to true when loading else false
  // but I have matched it to watch you mentioned in your post below
  // you may changed your it accordingly to your needs here 
  useEffect(() => {
    loading ? setDisabledState(false) : setDisabledState(true);
  }, [loading]);

  return (
    <>
      <span>{`${loading}`}</span>
      <button
        variant="contained"
        color="primary"
        onClick={() => importData()}
        disabled={disabledState}
      >
        Import
      </button>
    </>
  );
}

以下是上述指向CodeSandbox的链接:https://codesandbox.io/s/twilight-hill-urv8o?file=/src/App.js:0-1055