Donnie Berry
Donnie Berry

Reputation: 289

Update child prop when state changes through parent

I have a parent state which has a 'Theme' state.

Basically, this is the layout thus far.

Parent Component carries state of Theme.

Parent passes down current state to child component as "theme" prop using code "theme={this.state.theme}".

Trying to style child element inline with

style={{ background: props.theme === "light" ? "#fff" : "#000" }}

The problem is though, when the parent component state changes, the child component does NOT update. I console log the parent state when a toggle button is pressed to change the state between light/dark. The parent state updates fine, but the inline style does not change. Indicating that the child component is locked into whatever state is current when the page loads.

For e.g, if the default state is 'Dark', the child component will be stuck on 'Dark'. If I TOGGLE the parent state to 'Light', the child component will remain on 'Dark'.

Is there any reason for this?

I am new to react so sorry if this is a noob question!

Parent

import React, { useState } from "react";
import "./App.scss";
import TweetArea from "./components/TweetArea";
import SwitchTheme from "./components/SwitchTheme";
import Header from "./components/Header";
import html2canvas from "html2canvas";
import { render } from "@testing-library/react";

function screenshot() {
  html2canvas(document.querySelector("#tweetHere")).then((canvas) => {
    document.body.appendChild(canvas);
  });
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      theme: "light",
    };
  }

  toggleTheme = (props) => {
    this.setState({ theme: this.state.theme === "light" ? "dark" : "light" });
    console.log(this.state.theme);
  };

  themeSwitcher = () => {
    const selectedTheme = this.state.theme === "dark" ? "dark" : "";
    if (selectedTheme === "dark") {
      document.getElementByClass("tweetArea").style.background = "blue";
    }

    console.log("It ran");
  };

  render() {
    return (
      <div className="App">
        <button onClick={this.toggleTheme}>Toggle</button>
        <SwitchTheme theme={this.state.theme} />
        <Header />
        <TweetArea selectedTheme={this.state.theme} />
      </div>
    );
  }
}
export default App;

Child

import React, { useState } from "react";
import Tweet from "./Tweet";
import TweetUsername from "./TweetUsername";
import TweetTitle from "./TweetTitle";
import TweetTime from "./TweetTime";
import TweetData from "./TweetData";

const TweetArea = (props) => {
  const [TweetValue, setTweetValue] = useState("");
  const TweetHandler = (e) => {
    setTweetValue(e.target.value);
  };

  const [UsernameValue, setUsernameValue] = useState("");
  const UsernameHandler = (e) => {
    setUsernameValue(e.target.value);
  };

  const [TitleValue, setTitleValue] = useState("");
  const TitleHandler = (e) => {
    setTitleValue(e.target.value);
  };

  const [RetweetValue, setRetweetValue] = useState("");
  const RetweetHandler = (e) => {
    setRetweetValue(e.target.value);
  };

  return (
    <div class="tweetArea" style={{ background: props.selectedTheme }}>
      <div class="innerContainer">
        <div className="inputArea">
          <div class="tweetInput_tweet">
            <h5>Enter your Tweet</h5>
            <input type="text" class="onTweet" onChange={TweetHandler} />
          </div>
          <div class="tweetInput_username">
            <h5>What is the username</h5>
            <input type="text" onChange={UsernameHandler} />
          </div>
          <div class="tweetInput_title">
            <h5>What is the title</h5>
            <input type="text" onChange={TitleHandler} />
          </div>

          <div class="tweetInput_retweet">
            <h5>What is the retweet count</h5>
            <input type="text" onChange={RetweetHandler} />
          </div>
        </div>
        <div
          class="tweet"
          id="tweetHere"
          style={{ background: props.theme === "light" ? "#fff" : "#000" }}
        >
          <div class="tweet_header">
            <div class="tweet_avatar">
              <img
                src="https://via.placeholder.com/50"
                alt="avatar"
                class="avatar"
              />
            </div>
            <div class="tweet_person">
              <TweetTitle TitleValue={TitleValue} />
              <TweetUsername UsernameValue={UsernameValue} />
            </div>
          </div>

          <Tweet TweetValue={TweetValue} />
          <TweetTime />
          <TweetData RetweetValue={RetweetValue} />
        </div>
      </div>
    </div>
  );
};

export default TweetArea;

Upvotes: 1

Views: 1692

Answers (1)

Dan Philip Bejoy
Dan Philip Bejoy

Reputation: 4376

The prop is selectedTheme

<TweetArea selectedTheme={this.state.theme} />

You have used props.theme it should be props.selectedTheme

Upvotes: 1

Related Questions