简体   繁体   中英

How to set state based on document.body but before render (react)

I have a toggle whose defaultChecked I want to set based on the document.body.getAttribute("data-theme").

If the theme is light set the defaultChecked = "" and if not defaultChecked = "true"

I have realized that the problem is that the site is not fully loaded when I want to do something like this:

this.state = {
  checked: document.body.getAttribute("data-theme") === "light" ? "" : "true",
};

which means that I always get something truthy.

here is the complete component:

class Theme extends Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: document.body.getAttribute("data-theme") === "light" ? "" : "true",
    };
    this.handelChange = this.handelChange.bind(this);
  }

  componentDidMount() {
    let theme = localStorage.getItem("data-theme");
    document.body.setAttribute("data-theme", theme);
  }

  handelChange(evt) {
    if (evt.target.checked) {
      document.body.setAttribute("data-theme", "dark");
      localStorage.setItem("data-theme", "dark");
    } else {
      document.body.setAttribute("data-theme", "light");
      localStorage.setItem("data-theme", "light");
    }

    let lineColor = getComputedStyle(document.body).getPropertyValue("--sidebar-color");
    if (typeof InstallTrigger === "undefined") {
      lineColor = lineColor.substring(1);
    }
    this.props.colorChange(lineColor);
  };

  render() {
    return (
      <div onChange={this.handelChange} className="theme-switch-wrapper">
        <label className="theme-switch" htmlFor="checkbox">
          <input type="checkbox" id="checkbox" defaultChecked={this.state.checked} />
          <div className="slider round"></div>
        </label>
      </div>
    );
  }
}

export default Theme;

I think what you're trying to do is this:

class Theme extends Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: localStorage.getItem("data-theme") === "light" ? "" : "true"
    };
    this.handelChange = this.handelChange.bind(this);
  }

  componentDidMount() {
    let theme = localStorage.getItem("data-theme");
    this.setState({
      checked: theme === "light" ? "" : "true"
    });
  }

  handelChange(evt) {
    if (evt.target.checked) {
      localStorage.setItem("data-theme", "dark");
    } else {
      localStorage.setItem("data-theme", "light");
    }

    let lineColor = getComputedStyle(document.body).getPropertyValue(
      "--sidebar-color"
    );
    if (typeof InstallTrigger === "undefined") {
      lineColor = lineColor.substring(1);
    }
    this.props.colorChange(lineColor);
  }

  render() {
    return (
      <div onChange={this.handelChange} className="theme-switch-wrapper">
        <label className="theme-switch" htmlFor="checkbox">
          <input
            type="checkbox"
            id="checkbox"
            defaultChecked={this.state.checked}
          />
          <div className="slider round"></div>
        </label>
      </div>
    );
  }
}

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