简体   繁体   中英

Reactjs useState not changing boolean state and not rendering child component on click

I am trying to display the SingleLineText component below that has one input field when a click occurs in the parent component called TextInput . However, after a click, the state is not changed by useState and as a result the child component named SingleLineText is not displayed.

TextInput component is pasted below right after SingleLineText component.

SingleLineText component:

import React from "react";
const SingleLineText = () => {    
    return(
      <form>
        <input />
      </form>
    )
}
export default SingleLineText;

TextInput the Parent component for SingleLineText component:

import React, {useState, useEffect} from "react";
import SingleLineText from "./SingleLineText"

const TextInput = (props) => {

 const [showSingleText, setShowSingleText] = useState(false);

 useEffect( () => {
 }, [showSingleText])

 const handleFieldDisplay = (event) => {
    if (event.target.value == "Single line text") {
      cancel();
      setShowSingleText(showSingleText => !showSingleText);
      //setShowSingleText(showSingleText => true);
    }
  }

  const cancel = () => {
    props.setShowInput(!props.showInput);
  }

  return (
    <>
      <div className="dropdown">
        <ul key={props.parentIndex}>
          {
            props.fieldType.map( (val, idx) => {
              return(
               <option key={idx}  value={val} className="dropdown-item" onClick={handleFieldDisplay}> {val} </option>
              )
           })
        }

        </ul>
      </div>
     
      {showSingleText && <SingleLineText />}
    </>
  )

}
export default TextInput;

Topmost or grand parent component:

import React, { useState, useEffect, useRef } from "react"
import PropTypes from "prop-types"
import TextInput from "components/pod_table/fields/inputs/TextInput";

const DynamicFields = (props) => {
  const fieldType = ['Checkbox', 'Dropdown', 'boolean', 'Single line text'];
  const [showDynamicField, setShowDynamicField ] = useState(false);
  const[showInput, setShowInput] = useState(false);

  useEffect(() => {}, [showDynamicField, showInput]);
  
  const handleShowDynamicField = (event) => {
     setShowDynamicField(!showDynamicField);
  }
     
  const handleSubDisplay = (event) => {
     if (event.target.value == "customise field type") {
       setShowDynamicField(!showDynamicField);
       setShowInput(!showInput);
     }
  }
  
  return (
    <React.Fragment>
      <div>
      <i className="bi bi-chevron-compact-down" onClick={handleShowDynamicField}></i>
       { showDynamicField &&
            (<div className="dropdown">

             <ul key={props.parentIndex}>
             {
                optionsHash.map( (val, idx) => {
                 return(
                  <option key={idx}  value={val} className="dropdown-item" onClick={handleSubDisplay}> {val} </option>
                 )
               })
             }

             </ul>
            </div>) }

        {showInput && <TextInput fieldType={fieldType} setShowInput={setShowInput} showInput={showInput} /> }
        </div>
    </React.Fragment>
  )

}

The problem is that in the handleFieldDisplayFunction you are calling the cancel function which changes the parent state showInput and hence unmounts the TextInput component itself, so the showSingleText state changes inside TextInput component doesn't have any effect.

Design your code in a way that you are not required to unmount TextInput when you click on an option within it

 const handleFieldDisplay = (event) => {
    if (event.target.value == "Single line text") {
      setShowSingleText(showSingleText => !showSingleText);
    }
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM