为什么此功能组件在setState之后不重新呈现?

时间:2019-08-14 09:35:37

标签: javascript reactjs typescript components

如下所示,此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

5 个答案:

答案 0 :(得分: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)
    }
} 

答案 1 :(得分:2)

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

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 :(得分:1)

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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