1

I am currently rendering user input in a div, in the same component as my form. I want to render the user input on another page (in my other component) instead. How can I render the user input in a different component of my app?

Structure of app: App.js (navigation setup for react router) 3 components: Home.js, ProjectIdeas.js and Projects.js Planning.js (the component which contains my form and currently renders the user input) is the child of Projects.js. Projects.js is where I want to render the user input.

Planning.js

   constructor() {
     super()
     this.state = { 
       title: '',
       features: '',
      details: ''
        }

     this.handleChange = this.handleChange.bind(this)
     this.handleSubmit = this.handleSubmit.bind(this)
   }

handleChange(event) {

this.setState({ 
  [event.target.name]: event.target.value 
})
}

handleSubmit(event) {
    const {
      title,
       features,
      details
    } = this.state;
    event.preventDefault();
    this.setState({ title, features, details });
}

    render() {
      return (
        <form onSubmit={this.handleSubmit}>
 <div>{this.state.title}</div>
        <div>
          <label className="label-title">
            Project Title:</label>
            <input name="title" id="title" type="text" onChange={this.handleChange}/>
            </div>
        <div>
      <label className="label-features">
      Features:</label>
      <input name="features" placeholder="Button (directs to contact page), black footer" id="features" type="text" onChange={this.handleChange}/>
      </div>
      <div>
    <label className="label-details">
    Other details: </label>
    <input name="details" placeholder="Other Details" id="details" type="text" onChange={this.handleChange}/>
    </div>
          <input class="submit" type="submit" value="Save plan" />
        </form>
      )
    }
  }

Projects.js

class Projects extends React.Component {
    constructor(props) {
        super(props)
        this.state = { isEmptyState: true }
      }

      triggerAddPlanState = () => {
        this.setState({
          ...this.state,
          isEmptyState: false,
          isAddPlanState: true
        })
      }

    render() {
        return (
            <div>
            {this.state.isEmptyState && <AddPlanButton addPlan={this.triggerAddPlanState} />}

            {this.state.isAddPlanState && <Planning />}
            </div>

        )
    }
}
SK1dev
  • 1,049
  • 1
  • 20
  • 52
  • You mean you want to render the same exact form in another component? – goto Feb 05 '20 at 17:15
  • No, I want to render the user input (```
    {this.state.title}
    ```) in another component instead of rendering it in the same component as the form. Would I need to set up state in the other component? @goto1
    – SK1dev Feb 05 '20 at 17:22
  • 1
    You don't need to set up state in another component since this would be duplicating state (in your parent component and child). Instead, you can pass in `title`, `features`, `details` as [props](https://reactjs.org/docs/components-and-props.html) to your child components. It would help us answer if we could see how you are structuring the components in your application. – kennyvh Feb 05 '20 at 17:33
  • 1
    You should take a look at this - https://reactjs.org/docs/lifting-state-up.html or as @khuynh suggested, look into `Context API` and/or `Redux` to share state across multiple components. – goto Feb 05 '20 at 17:39
  • I have updated my question to show how I'm structuring the components. Is it possible to pass the input to the other component without using context or redux? @khuynh – SK1dev Feb 05 '20 at 18:03
  • Yes, you'll need [lift the state up](https://reactjs.org/docs/lifting-state-up.html), see the answer from @ray hatfield. In your case, you'll lift up the `title`, `features`, and `details` to `Projects.js` and pass them as props into `AddPlanButton` and `Planning`. – kennyvh Feb 05 '20 at 18:06
  • Great, thanks! I now have a better understanding of what to do. @khuynh – SK1dev Feb 05 '20 at 18:08

1 Answers1

3

You'll need to store the value outside the component, either in a common parent component or somewhere orthogonal.

If the components share a nearby parent, you can have the parent keep track of the state and pass it down as props to both:

function ParentComponent () {
  const [value, setValue] = React.useState();

  <ComponentA value={value} onChange={v => setValue(v)} />
  <ComponentB value={value} onChange={v => setValue(v)} />
}

There are many other ways to do it if your app doesn't lend itself to the above solution. I'd recommend you consider using a store like Redux or possibly look at React Context. (Your scenario doesn't seem like a good use of context but you could make it work.)

Implementing your own store is not particularly complicated. Here's an example of one way to do it.

ray
  • 26,557
  • 5
  • 28
  • 27