0

When my app loads the query below runs and the result from the DB is displayed in the browser. However, my app also has a submit button. How can run this entire component when the submit button is pressed while passing the timestamp input from the submit?

handleSubmit(event) {
  event.preventDefault();
  console.log(this.state.inputValue)
  this.state = {
    inputValue: new Date(document.getElementById("time").value).valueOf()
  };
  console.log(this.state);            
}

This is the UserList component code:

const UserList = props => (
  <Query
    query={gql`
      query action($timestamp: Float!) {
        action(timestamp: $timestamp) {
          action
          timestamp
          object {
            filename
          }
        }
      }
    `}
  >
    {({ loading, error, data }) => {
      if (loading) return <p>Loading...</p>;
      if (error) return <p>Error</p>;

      return (
        <Item.Group divided>
          {data.action.map(action => (
            <div>
              <ul>
                <li>{action.action}</li>
                <li>{action.timestamp}</li>
                <ul>
                  {action.object.map(obj => {
                    return <li>{obj.filename}</li>;
                  })}
                </ul>
              </ul>
            </div>
          ))}
        </Item.Group>
      );
    }}
  </Query>
);

export default UserList;
Tholle
  • 108,070
  • 19
  • 198
  • 189
N6DYN
  • 325
  • 1
  • 3
  • 17

2 Answers2

1

Parent component contains submit button and there lives state. Submit handler should only set value in state with ... setState() - NOT directly!

If there is no default state/value use conditional rendering ... in parent render display some placeholder when state (timestamp) is undefined. If value exists pass it as prop:

{!this.state.inputValue ? <SomePlaceholder />
: <UserList timestamp={this.state.inputValue} />}
// place input, submit button where you want (after/before results)

UserList will be called with props - 'props.timestamp' can be used in graphql query literal.

When input changes again submit handler will change parent state and that change will be passed again as prop to child, query fired, results rerendered.

xadm
  • 8,219
  • 3
  • 14
  • 25
  • `handleSubmit(event) { event.preventDefault(); console.log(this.state.inputValue) this.state = {inputValue: new Date(document.getElementById("time").value ).valueOf()}; {!this.state.inputValue ? : } }` – N6DYN Aug 01 '18 at 22:05
  • Thanks for the explanation. It makes sense logically but I'm having issues with the syntax (as always). No sure what I am supposed to do with . – N6DYN Aug 01 '18 at 22:13
  • Don't treat it literaly ;) It's an abstract flow description. Read docs/basic examples about setState - this is must have knowledge (you're doing wrong). is a fictional component you can define and use in this place. Don't multimply errors - handle things step by step. – xadm Aug 01 '18 at 22:15
  • `handleSubmit(event) { event.preventDefault(); console.log(this.state.inputValue) this.setState = {inputValue: new Date(document.getElementById("time").value ).valueOf()}; {!this.state.inputValue ?

    Loading...

    : } }`
    – N6DYN Aug 01 '18 at 22:17
  • The above fixed the error. However nothing happens about I change click submit after selecting a time and date. – N6DYN Aug 01 '18 at 22:18
  • `handleSubmit(event) { event.preventDefault(); console.log(this.state.inputValue) this.setState = {inputValue: new Date(document.getElementById("time").value ).valueOf()}; {!this.state.inputValue ?

    Loading...

    : } }`
    – N6DYN Aug 01 '18 at 22:26
  • Made the above changes but nothing shows up in the browser after clicking the submit button. – N6DYN Aug 01 '18 at 22:28
  • read docs!! setState() function https://reactjs.org/docs/state-and-lifecycle.html minimum state, events, forms ... in this case – xadm Aug 01 '18 at 22:32
  • So according to the documentation the following line should re-render the dispaly but it is not: this.setState = {inputValue: new Date(document.getElementById("time").value ).valueOf()}; – N6DYN Aug 01 '18 at 22:38
  • I would not be surprise if there is bug. Since I started this project there has been several workarounds I had to implement due to bugs. If only things would work as documented. Anyway, thanks for your help. – N6DYN Aug 01 '18 at 22:41
  • Like I was saying https://stackoverflow.com/questions/24718709/reactjs-does-render-get-called-any-time-setstate-is-called?rq=1: "You can write your own implementation of shouldComponentUpdate method for your component, but default implementation always returns true - meaning always re-run render function." – N6DYN Aug 01 '18 at 22:45
  • So, I'm using setState like the documentation states but when I press the submit button nothing happens... – N6DYN Aug 01 '18 at 22:47
  • WHERE IN DOCS you found that???? where do you use setState() FUNCTION ??? LEARN BASICS about setting state and passing props to children!! – xadm Aug 01 '18 at 22:47
0

Base on the information provided, there's probably several ways to accomplish what you need. I would say the UserList component needs to conditionally render the Query component in some manner. Perhaps UserList takes a boolean prop isSubmitted and while isSubmitted is false, UserList renders a div with text explaining to submit the query. This could be done as the UserList and the submit button being hosted by the same parent component that has state containing a isSubmitted property that changes on click.

spakmad
  • 880
  • 6
  • 15
  • So calling this component from the submit button cannot be accomplished based on the syntax? – N6DYN Aug 01 '18 at 20:35
  • You can call the functional component from within the `handleSubmit`. That will return the JSX, but the `Query` component won't actually be mounted until you render it. Maybe pass in the timestamp as a prop. – spakmad Aug 01 '18 at 20:47
  • I am very new to ReactJS. So will this work: this.props.UserList? – N6DYN Aug 01 '18 at 20:52