简体   繁体   中英

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 eg, 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;

The prop is selectedTheme

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

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

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