Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

112
Views
Updating React.Component state from prop

I'm attempting to update a React.Component with data that can be changed by its parent. However, the component that is receiving the prop is not updating it state after receiving the prop.

For example, I have a parent function here called Edit. This creates its state to include a title field to be "". It then calls Firebase and lists out all the widgets that are in firebase for the user to see as buttons. Finally, when a user clicks on one of the widgets that was listed out, it then updates that title to be the value in firebase.

At the very bottom of this I have a component called WidgetManipulation. Here I'm attempting to pass this title down into the prop to be used. The title can change based on which of the buttons the user clicks to see more info on

export default function Edit() {
  const [firebaseWidgetData, SetFirebaseWidgetData] = useState({ 
    title: "",
  });

  const [dashboardWidgets, dashboardWidgetsLoading, dashboardWidgetsError] =
    useCollection(collection(firestore, "Widgets"), {
      snapshotListenOptions: { includeMetadataChanges: true },
    });

  const getWidgetInfoToEdit = async ({ target: { value } }) => {
    const dashboardWidgetsDocRef = doc(firestore, "Widgets", value.toString());
    const docSnap = await getDoc(dashboardWidgetsDocRef);
    SetFirebaseWidgetData(JSON.parse(JSON.stringify(docSnap.data())));
  }

  return (
    <div className={styles.container}>
      {dashboardWidgetsError && (
        <strong>Error: {JSON.stringify(error)}</strong>
      )}
      {dashboardWidgetsLoading && <span>Collection: Loading...</span>}
      {dashboardWidgets && (
        <span>
          {dashboardWidgets.docs.map((doc) => (
            <button key={doc.id} value={doc.id} onClick={getWidgetInfoToEdit}>
              {`${doc.id} - 
                  ${doc.data().title}`}
            </button>
          ))}
        </span>
      )}
      <WidgetManipulation isCreate={false} firebaseWidgetData={firebaseWidgetData}></WidgetManipulation>
  </div>
  );
}

The main problem I'm running into is that the WidgetManipulation component does not ever receive an updated state value based on the firebaseWidgetData prop that I pass down.

My WidgetManipulation code is so:

export default class WidgetManipulation extends Component {

  constructor(props) {
    super(props);
    this.state = {
      widgetData: {
        title: props.firebaseWidgetData.title,
      }
    }
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
         id="title"
         name="title"
         type="text"
         required
         value={this.state.widgetData.title}
         onChange={this.handleChange}
        />
        <label htmlFor="title">Title</label>
      </form>
    )
  }
}
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0


Since it is a child component, you can just directly pass the prop variable inside the value attribute like this:

<input
     id="title"
     name="title"
     type="text"
     required
     value={this.props.firebaseWidgetData.title}
     onChange={this.handleChange}
/>

React will simply re-renders your parent component along with its child components, hence you won't need a state inside your child component. If you want your child component to have state based on the props you have passed, you can listen to the prop changes by using the componentDidMount and componentWillUnmount methods (if you are using React Class Component) and useEffect hook (if you are using React Functional Component).

EDIT:

Since the author wants the input field to be useable, we can simply pass the setFirebaseWidgetData. In your parent component, pass the setter function:

<WidgetManipulation isCreate={false} firebaseWidgetData={firebaseWidgetData} setFirebaseWidgetData={SetFirebaseWidgetData}></WidgetManipulation>

In the child component, simply use the setter function that we have passed.

export default class WidgetManipulation extends Component {

  constructor(props) {
    super(props);
    this.state = {
      widgetData: {
        title: props.firebaseWidgetData.title,
      }
    }
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
         id="title"
         name="title"
         type="text"
         required
         value={this.props.firebaseWidgetData.title}
         onChange={(e) => {
              this.props.setFirebaseWidgetData({
                   title: e.target.value
              })
         }}
        />
        <label htmlFor="title">Title</label>
      </form>
    )
  }
}
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!