Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setState outside Component

I'm having trouble with the following code:

My component:

class Landing extends Component {

  state = {
    loginMethod: '',
    tournamentCode: -1,
  }
}

My const:

const Code = () => (
  <div className="" style={{marginTop: 20}}>
     <input
      className=""
      style={{lineHeight: 1, height: 30, border:0, paddingLeft: 5}}
      placeholder="Tournament Code"
      onChange={e => this.setState({tournamentCode: e.target.value})} />
    <Link to="/App">
      <button className="" style={{marginLeft: 10, border: 0, outline:        
          'none', background: '#efefef', height: 30, width: 80}}> Enter </button>
    </Link>
  </div>
)

Both of them are in the same Landing.js file.

I know my problem is that I try to do this.setState outside the Landing class. Are there any solutions for this problem? Or is there a better way I should program this?

I've also read some things about redux and contexts in React. Which of these is my best way to go? Or are there more easy solutions?

like image 984
Milebril Avatar asked Oct 17 '25 18:10

Milebril


1 Answers

Short answer: No, you cannot setState outside a component.

Long answer: You cannot directly modify the component's state outside it, but you can always create a method that changes the state, then pass it down as props to <Code /> component. Example code (<Link /> component has been removed for simplicity)

import React, { Component } from "react";
import ReactDOM from "react-dom";

class Landing extends Component {
  state = {
    loginMethod: "",
    tournamentCode: -1
  };

  onChange = e => {
    this.setState({
      tournamentCode: e.target.value
    });
  };

  render() {
    //You can use <></> or <React.Fragment></React.Fragment>
    //I printed out the state to show you that it has been updated
    return (
      <>
        <div>{this.state.tournamentCode}</div>
        <Code onChange={this.onChange} />
      </>
    );
  }
}

const Code = ({ onChange }) => (
  <div style={{ marginTop: 20 }}>
    <input
      style={{ lineHeight: 1, height: 30, border: 0, paddingLeft: 5 }}
      placeholder="Tournament Code"
      onChange={onChange}
    />
    <button
      style={{
        marginLeft: 10,
        border: 0,
        outline: "none",
        background: "#efefef",
        height: 30,
        width: 80
      }}
    >
      Enter
    </button>
  </div>
);

const rootElement = document.getElementById("root");
ReactDOM.render(<Landing />, rootElement);

Important: No Redux or context is needed. Learn the basics and try thinking of the most simple solution to a problem, then extend it further. Not in this case, but that's a good learning approach you should apply

Codesandbox for future reference: https://codesandbox.io/s/n1zj5xm24

like image 147
Brian Le Avatar answered Oct 19 '25 08:10

Brian Le