微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

自定义钩子中的状态未更新

如何解决自定义钩子中的状态未更新

我无法从自定义挂钩获取更新状态。 这个例子很简单。这是一个自定义钩子,允许从暗主题切换到亮主题自定义钩子内,我使用 useMemo 返回一个记忆值,但每次我用 switchOn 更新状态时,这似乎都不会更新。

我不想在这个例子中使用上下文

import { useState,useMemo,useCallback } from "react";

const useTheme = (initial) => {
  const [isOn,turnOn] = useState(false);
  const switchOn = useCallback((e) => turnOn(e.target.checked),[turnOn]);
  return useMemo(() => {
    return {
      theme: isOn ? "light" : "dark",buttonTheme: isOn ? "dark" : "light",lightsIsOn: isOn ? "On" : "Off",isChecked: isOn,switchOn,};
  },[switchOn,isOn]);
};
export default useTheme;

import { useState,useRef,useReducer } from "react";
import useTheme from "./useTheme";
import todos from "./reducer";
import "./App.css";

const Item = ({ id,text,done,edit,remove }) => {
  const { buttonTheme } = useTheme();
  const isDone = done ? "done" : "";
  return (
    <div style={{ display: "flex" }}>
      <li className={isDone} key={id} onClick={() => edit(id)}>
        {text}
      </li>
      &nbsp;
      <button type="button" onClick={() => remove(id)} className={buttonTheme}>
        <small>x</small>
      </button>
    </div>
  );
};

const SwitchInput = () => {
  const { switchOn,isChecked,lightsIsOn } = useTheme();
  return (
    <>
      <label class="switch">
        <input type="checkBox" onChange={switchOn} checked={isChecked} />
        <span class="slider round"></span>
      </label>
      &nbsp;
      <span>
        {" "}
        Lights <b>{lightsIsOn}</b>
      </span>
      <br /> <br />
    </>
  );
};

const initialState = {
  items: [],};
const init = (state) => {
  return {
    ...state,items: [
      { id: 1,text: "Learning the hooks",done: false },{ id: 2,text: "Study JS",{ id: 3,text: "Buy conference ticket",],};
};
function App() {
  const inputRef = useRef();
  const [state,dispatch] = useReducer(todos,initialState,init);
  const [inputValue,setInputValue] = useState(null);
  const { theme } = useTheme();

  const handleOnChange = (e) => setInputValue(e.target.value);
  const handleOnSubmit = (e) => {
    e.preventDefault();
    dispatch({ type: "add",payload: inputValue });
    inputRef.current.value = null;
  };

  return (
    <div className={`App ${theme}`}>
      <SwitchInput />
      <form onSubmit={handleOnSubmit}>
        <input ref={inputRef} type="text" onChange={handleOnChange} />
        <ul>
          {state.items.map((item) => (
            <Item
              {...item}
              key={item.id}
              remove={(id) => dispatch({ type: "remove",payload: { id } })}
              edit={(id) => dispatch({ type: "edit",payload: { id } })}
            />
          ))}
        </ul>
      </form>
    </div>
  );
}
export default App;
  1. 我的自定义钩子:useTheme.js
  2. 下面,我想从自定义钩子访问逻辑的组件:App.js

我使用 App.css 来应用主题样式:深色和浅色

下面是一个演示。我们可以看到值没有改变

enter image description here

订阅状态更改的有效方法是如何在组件之间共享全局状态?

解决方法

您需要将 useTheme() 的值从 <App> 传递给 <SwitchInput> 才能共享,如下所示。

function App() {
  const { theme,switchOn,isChecked,lightsIsOn } = useTheme();

  return (
    <div className={`App ${theme}`}>
      <SwitchInput
        switchOn={switchOn}
        isChecked={isChecked}
        lightsIsOn={lightsIsOn}
      />
    </div>
  );
}

然后,<SwitchInput> 将在道具中接收它们。

const SwitchInput = ({ switchOn,lightsIsOn }) => {
  return (
    <>
      <label class="switch">
        <input type="checkbox" onChange={switchOn} checked={isChecked} />
        <span class="slider round"></span>
      </label>
      &nbsp;
      <span>
        {" "}
        Lights <b>{lightsIsOn}</b>
      </span>
      <br /> <br />
    </>
  );
};

在您的示例中,useTheme()<App><SwitchInput> 中都被调用,但 theme 和其他值是单独初始化的,并且不会在每个组件之间共享。>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?