【问题标题】:Why this function component doesn't re-render after setState?为什么这个函数组件在 setState 之后不重新渲染?
【发布时间】:2019-12-20 20:30:58
【问题描述】:

如下所示,这个TextInput组件做了一个简单的工作:当输入的值为空时,隐藏标题,因为占位符显示相同的单词。

但是代码没有按预期工作。 InputEvent 确实运行,但重新分配 activeStyle 无效。

import React, {useState} from 'react';
import './TextInput.css';
import * as CSS from 'csstype';

type TextInputProps = {
    title: string
}

const TextInput: React.FC<TextInputProps> = ({title, children}) => {

    const hiddenStyle: CSS.Properties = {
        opacity: 0
    };
    const visibleStyle: CSS.Properties = {
        opacity: 1
    };
    let activeStyle = hiddenStyle

    const [rawTextInput, setRawTextInput] = useState("")

    const InputEvent = (e: React.FormEvent<HTMLInputElement>) => {
        const inputValue = e.currentTarget.value;
        setRawTextInput(inputValue)

        if(inputValue == ""){
            activeStyle = hiddenStyle
        } else {
            activeStyle = visibleStyle
        }

    }

    return (
        <div className="TextInput">
            <p 
                className="TextInputTitle"
                style={activeStyle}
            >
                {title}
            </p>
            <input 
                className="TextInputField" 
                type="text" 
                placeholder={title} 
                value={rawTextInput}
                onChange={InputEvent}
            />
            {/*<p className="TextInputHint"></p>*/}
        </div>
    );
}

export default TextInput
import React, {useState} from 'react';
import './TextInput.css';
import * as CSS from 'csstype';

type TextInputProps = {
    title: string
}

const TextInput: React.FC<TextInputProps> = ({title, children}) => {

    const hiddenStyle: CSS.Properties = {
        opacity: 0
    };
    const visibleStyle: CSS.Properties = {
        opacity: 1
    };
    let activeStyle = hiddenStyle

    const [rawTextInput, setRawTextInput] = useState("")

    const InputEvent = (e: React.FormEvent<HTMLInputElement>) => {
        const inputValue = e.currentTarget.value;
        setRawTextInput(inputValue)

        if(inputValue == ""){
            activeStyle = hiddenStyle
        } else {
            activeStyle = visibleStyle
        }

    }

    return (
        <div className="TextInput">
            <p 
                className="TextInputTitle"
                style={activeStyle}
            >
                {title}
            </p>
            <input 
                className="TextInputField" 
                type="text" 
                placeholder={title} 
                value={rawTextInput}
                onChange={InputEvent}
            />
            {/*<p className="TextInputHint"></p>*/}
        </div>
    );
}

export default TextInput

【问题讨论】:

标签: javascript reactjs typescript components


【解决方案1】:

我尝试了一种更简单的方法

import React, { useState } from "react";

type TextInputProps = {
  title: string;
};

const TextInput: React.FC<TextInputProps> = ({ title, children }) => {

  const [rawTextInput, setRawTextInput] = useState("");

  const InputEvent = (e: React.FormEvent<HTMLInputElement>) => {
    setRawTextInput(e.target.value)
  };

  return (
    <div className="TextInput">
      <p className="TextInputTitle" style={{opacity : rawTextInput == ""  ? 0 : 1}}>
        {title}
      </p>
      <input
        className="TextInputField"
        type="text"
        placeholder={title}
        value={rawTextInput}
        onChange={InputEvent}
      />
      {/*<p className="TextInputHint"></p>*/}
    </div>
  );
};

export default TextInput;

希望对你有用

【讨论】:

    【解决方案2】:

    局部变量不影响重新渲染。

    let activeStyle = hiddenStyle    //local variable
    

    你需要保持这个状态并使用 setter 方法进行更改。

    const [activeStyle, setActiveStyle] = useState(hiddenStyle)
    
    const InputEvent = (e: React.FormEvent<HTMLInputElement>) => {
        const inputValue = e.currentTarget.value;
        setRawTextInput(inputValue)
    
        if(inputValue == ""){
            setActiveStyle(hiddenStyle)
        } else {
            setActiveStyle(visibleStyle)
        }
    } 
    

    【讨论】:

      【解决方案3】:
      import React, {useState} from 'react';
      import './TextInput.css';
      import * as CSS from 'csstype';
      
      type TextInputProps = {
          title: string
      }
      
      const TextInput: React.FC<TextInputProps> = ({title, children}) => {
      
          const hiddenStyle: CSS.Properties = {
              opacity: 0
          };
          const visibleStyle: CSS.Properties = {
              opacity: 1
          };
      
          const [rawTextInput, setRawTextInput] = useState("")
      
          //------Put something you want to change dynamically inside useState()
          const [titleStyle, setTitleStyle] = useState(hiddenStyle)
          //------
      
          const InputEvent = (e: React.FormEvent<HTMLInputElement>) => {
              const inputValue = e.currentTarget.value;
              setRawTextInput(inputValue)
      
              if(inputValue == ""){
                  setTitleStyle(hiddenStyle)
              } else {
                  setTitleStyle(visibleStyle)
              }
      
          }
      
          return (
              <div className="TextInput">
                  <p 
                      className="TextInputTitle"
                      style={titleStyle}
                  >
                      {title}
                  </p>
                  <input 
                      className="TextInputField" 
                      type="text" 
                      placeholder={title} 
                      value={rawTextInput}
                      onChange={InputEvent}
                  />
                  {/*<p className="TextInputHint"></p>*/}
              </div>
          );
      }
      
      export default TextInput
      

      【讨论】:

        【解决方案4】:

        只需将 useState 用于 activeStyle 而不是在组件的范围内声明它,这可能会导致不同步效果,这可能是一个问题和不确定性

        【讨论】:

          【解决方案5】:

          更改局部变量的值不会导致重新渲染。即使其他原因导致渲染,新的渲染也无法访问前一个渲染的局部变量。您需要将 useState 用于活动样式,而不是局部变量。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-08-08
            • 2017-07-12
            • 2019-01-24
            • 1970-01-01
            • 1970-01-01
            • 2021-12-06
            • 1970-01-01
            相关资源
            最近更新 更多