0

I want to get the result of a query and use it for a button function, to change the state of the parent component. In this code example, the state of the parent component contains an ID which is used to display some stuff later. I want to create a button for every set of data of my data base and use the ID of the sets to change the state. But when I implement it like this the ID changes to "NaN". Is there any possible way to make this work?

class TestClass extends React.Component{

  constructor(props) {
    super(props);
    this.handleNewID = this.handleNewID .bind(this);
    this.state = {
      ID: 0,
    };
  }

  handleNewID ({id}){
    this.setState({ID: id});
  }

  render(){
    const props={
      handleNewID :this.handleNewID ,
    }

    return(
      <div>
          <TestFunction props={props}/>
      </div>)
    
  }
}

 function TestFunction ({props}){

  const {loading, error, data} = useQuery(GET_SOMETHING);
  
  if (loading) return <p>Loading ...</p>;
  if (error) return <p>Error ... ${JSON.stringify(error, null, 2)}</p>;
  if (data) 
  return data.something.map(({ id }) => (
    <div>
      <button onClick={ () => props.handleNewID ({id})}> Test Button </button>
    </div>));
}

1 Answer 1

1

A lot of stuff to tackle here; I decided to include comments in the code rather than describe my changes in the answer.

This might not solve the issue but it should guide you toward troubleshooting.

class TestClass extends React.Component {
  constructor(props) {
    super(props);
    this.handleNewID = this.handleNewID.bind(this); // removed space, probably copy/paste issue
    this.state = {
      ID: 0,
    };
  }

  handleNewID(id) {
    if(isNaN(id)) { // if we get NaN we log out to see what value id is, this will help us with troubleshooting
      console.log(`Id is NaN. Current value of id: ${id}`)
    }

    // no need to wrap in braces
    this.setState({ ID: Number(id) }); // try to convert to Number to be consisten with data types
  }

  render() {
    // removed props object since it can be confusing
    // instead we're passing the handler directly as an onClick-property
    return (
      <div>
        <TestFunction onClick={this.handleNewID} />
      </div>
    );
  }
}

function TestFunction({ onClick }) {
  const { loading, error, data } = useQuery(GET_SOMETHING);
  if (loading) return <p>Loading ...</p>;
  if (error) return <p>Error ... ${JSON.stringify(error, null, 2)}</p>;
  if (data) {
    return data.something.map(({ id }) => (
      <div>
        <button onClick={() => onClick(id)}>Test Button</button>
      </div>
    ));
  }
  return null; // always need to return something from a component
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.