1

I'm a bit confused regarding the 'value' parameter and it's assignment.

From here Can't type in React input text field I understood that when setting a value parameter, that disables the possibility of entering a value to the input box

enter image description here

YET, if we notice the following code (with a focus on the render method - I will put the whole code in the bottom of this question):

import React, { Component } from 'react'

export default class NewBoxForm extends Component {
  constructor(props){
    super(props);
    this.state = {
        height: "",
        width: "",
        backgroundColor: ""
    }
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  
  handleChange(evt){ //handles any form of change in the input.
    evt.preventDefault(); // prevents refresh of page
    this.setState({
        [evt.target.name]: evt.target.value
    });
  }

  handleSubmit(evt){
    evt.preventDefault();
    console.log(this.state)
    this.props.handleSubmit(this.state);
    
    //need to use my parent's function to transfer information to parent.
    //for that i will send my state, and he will update his state.
  }

  
    render() {


    return (
      <form onSubmit={this.handleSubmit}>
        <label htmlFor='height'>Height: </label>
        <input
        name='height'
        id='height'
        type="number"
        value={this.state.height}
        onChange={this.handleChange}
        />

        <label htmlFor='width'>Width: </label>
        <input
        name='width'
        id='width'
        type="number"
        value={this.state.width}
        onChange={this.handleChange}
        />

        <label htmlFor='backgroundcolor'>BackgroundColor: </label>
        <input
        name='backgroundcolor'
        id='backgroundcolor'
        type="text"
        value={this.state.backgroundColor}
        onChange={this.handleChange}
        />

        <button>Submit</button>
      </form>
    )
  }
}

which works! i'm able this way to insert a value to the input tag..

so, my question is, what is the rule of thumb? what is correct the correct way? good habit vs bad hobbit (:D)

rest of the code:

import React, { Component } from 'react';
import Box from './Box';
import NewBoxForm from './NewBoxForm';

 class BoxList extends Component {
    constructor(props){
        super(props);
        this.state = {
            boxes: [
                { width: 10, height: 20, backgroundColor: "red" },
                { width: 20, height: "200px", backgroundColor: "purple" },
                { width: "100px", height: "140px", backgroundColor: "yellow" },
            ]
        };
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    // what i will get from my child(Box) ? A BOX, duh.
    handleSubmit(newBox){ 
        this.setState(st => ({
            boxes: [...st.boxes, newBox]
    }))
    console.log(this.state);
        
    }

  render() {
    let boxes2show = this.state.boxes.map(box => (
            <Box 
            width={box.width} 
            height={box.height} 
            backgroundColor={box.backgroundColor}/>
    ))

    return (
      <div>
        <h1>BoxList</h1>
        <NewBoxForm handleSubmit={this.handleSubmit}/>
        {boxes2show}


      </div>
    )
  }
}

export default BoxList;



import React, { Component } from 'react'

export default class Box extends Component {
    constructor(props){
        super(props);
    }

    render() {
        const myStyle = {
            backgroundColor: this.props.backgroundColor,
            width: `${this.props.width}em`,
            height: `${this.props.height}em`
        };
    return (
      <div style={myStyle}>
        I'm a box.
        sa
        </div>
    )
  }
}

cheers

dani_l_n
  • 376
  • 1
  • 11

1 Answers1

2

I think you misunderstood the answer. In React, inputs came in two variants (see Docs):

  • controlled
  • uncontrolled

Controlled inputs are given a value={valueState} to it, which prevents any changes from the user if valueState isn't updated inside the component. The following example is a controlled input, that can't be changed, because it has no change event handler:

export default function App() {

  const value = 'test';

  return (
    <div className="App">
      <input value={value} />
    </div>
  );
}

To allow user input, you need to react to changes:


export default function App() {

  const [value, setValue] = useState('test')
  

  return (
    <div className="App">
      <input value={value} onChange={(e) => setValue(e.currentTarget.value)} />
    </div>
  );
}

On the other hand there are uncontrolled inputs. Those don't receive a value input. But they can receive a defaultValue (React speciality) to allow initialy setting a value to it a user can change:

export default function App() {
  const value = "test";
  const ref = useRef();
  
  const submit = (e) => {
    e.preventDefault();

    // get data
    console.log(ref.current.value);
  };

  return (
    <form className="App" onSubmit={submit}>
      <input defaultValue={value} ref={ref} />
      <button>Submit</button>
    </form>
  );
}

Felix
  • 2,531
  • 14
  • 25
  • Thanks! That really made it clear. There was indeed a small piece of information that I was missing. :) – dani_l_n Sep 19 '22 at 07:53