0

As shown below, this TextInput component does a simple job: when input's value is empty, hides the title because placeholder shows the same words.

But the code doesn't work as expected. InputEvent does run, but reassign activeStyle has no effect.

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
0

5 Answers 5

1

Local variable doesn't affect re-render.

let activeStyle = hiddenStyle    //local variable

You need to keep this in state and change using setter method.

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)
    }
} 
Sign up to request clarification or add additional context in comments.

Comments

1

I've tried a simpler approach

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;

I hope it'll be useful

Comments

0

Changing the value of a local variable does not cause a re-render. And even if something else causes a render, that new render won't have access to local variables from the previous render. You need to use useState for the active style, not a local variable.

Comments

0

just use useState for activeStyle instead of declaring it on the scope of the component,this could cause unsync effect which could be a problem and indeterministic

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.