首页 > 解决方案 > 改变状态时输入值不更新

问题描述

在为学习目的创建一个小项目时,我遇到了更新输入值的问题。这是组件(我已尝试将其减少到最低限度)。

function TipSelector({selections, onTipChanged}: {selections: TipSelectorItem[], onTipChanged?:(tipPercent:number)=>void}) {
    
    const [controls, setControls] = useState<any>([]);
    const [tip, setTip] = useState<string>("0");

    function customTipChanged(percent: string)  {
        setTip(percent);
    }

    //Build controls
    function buildControls()
    {
        let controlList: any[] = [];
        controlList.push(<input className={styles.input} value={tip.toString()} onChange={(event)=> {customTipChanged(event.target.value)}}></input>);
        setControls(controlList);
    }
    
    useEffect(()=>{
        console.log("TipSelector: useEffect");
        buildControls();

        return ()=> {
            console.log("unmounts");
        }
    },[])
    
    console.log("TipSelector: Render -> "+tip);
    return (
        <div className={styles.tipSelector}>
            <span className={globalStyles.label}>Select Tip %</span>
            <div className={styles.btnContainer}>
                {
                   controls
                }
            </div>
        </div>
    );
}

如果我将输入的创建直接移动到 return() 语句中,则值会正确更新。

标签: reactjstypescriptstate

解决方案


我会将您的输入移出该组件,并让他们在 TipSelector 之外管理自己的状态。

看:

https://codesandbox.io/s/naughty-http-d38w9

例如:

import { useState, useEffect } from "react";
import CustomInput from "./Input";

function TipSelector({ selections, onTipChanged }) {
  const [controls, setControls] = useState([]);

  //Build controls
  function buildControls() {
    let controlList = [];
    controlList.push(<CustomInput />);
    controlList.push(<CustomInput />);
    setControls(controlList);
  }

  useEffect(() => {
    buildControls();

    return () => {
      console.log("unmounts");
    };
  }, []);

  return (
    <div>
      <span>Select Tip %</span>
      <div>{controls}</div>
    </div>
  );
}

export default TipSelector;

import { useState, useEffect } from "react";

function CustomInput() {
  const [tip, setTip] = useState("0");

  function customTipChanged(percent) {
    setTip(percent);
  }

  return (
    <input
      value={tip.toString()}
      onChange={(event) => {
        customTipChanged(event.target.value);
      }}
    ></input>
  );
}

export default CustomInput;


推荐阅读