DEV Community

Discussion on: React, React-Router and Fetch API

Collapse
 
ekimkael profile image
Ekim Kael • Edited

it didn't work.
There is some styledComponent code that i remove
Here is my code:


export default class Work extends Component {
  constructor(props) {
    super(props)
    const { match: { params } } = this.props

    this.state = { 
      url: params.work, 
      loading: true, 
      work: [],
      otherWorks: []
    }
  }

  handleClick = () => {
    const { url, loading } = this.state 
    this.setState({
      loading: !loading,
      url
    })

    fetch(`/w/${url}`)
      .then(res => res.json())
      .then(work => this.setState({ work: work }))
      .then(fetch(`/works?&_limit=6&id_ne=${url}`)
          .then(res => res.json())
          .then(others =>
            this.setState({ otherWorks: others, loading: false, url: this.props.match.params.work })))
  }



  componentDidMount = () => {
    this.handleClick()
  }

  render() {    
    console.log(this.state)
    const { loading, work, otherWorks } = this.state 

    if (loading) {
      return <Loader />
    } else {
    return <WorkWidget>
        <Cover>
          <Carousel />
          <Details>
          <Title>{work.name}</Title>
            <Paragraph>{work.desc}</Paragraph>
            <Row>
              <Section>
                <Subtitle>Client</Subtitle>
                <Info>{work.client}</Info>
              </Section>
              <Section>
                <Subtitle>Role</Subtitle>
                <Info>Fullstack</Info>
              </Section>
              <Section>
                <Subtitle>Url</Subtitle>
                <InfoUrl href={work.url} target="_blank" rel="noopener noreferrer">Visit</InfoUrl>
              </Section>
            </Row>
          </Details>
        </Cover>
        <OtherWorks>
          {otherWorks.map(otherWork => [
          <Link key={otherWork.id} to={`/w/${otherWork.id}`} onClick={this.handleClick}>
              <Works>
                <section>
                  <AppName>{otherWork.name}</AppName>
                  <Category>
                    {otherWork.category}
                  </Category>
                </section>
              </Works>
            </Link>
          ])}
        </OtherWorks>
      </WorkWidget>
    }
  }
}
Collapse
 
dance2die profile image
Sung M. Kim • Edited

Hi @iamkael .

Call fetch as a callback of this.setState().

this.setState({
    loading: !loading,
    url
}, () => fetch(`/w/${url}`).<rest of the chain>...)

My guess is that, handleClick's first this.setState sets the loading property, which is not properly recognized as this.setState is an asynchronous operation.

You'd fetch after loading property is turned off if you want such a synchronous behavior.

Collapse
 
nqbinh17 profile image
nqbinh17

Hey, I got the same problem with you. If you use HashRouter and click on its siblings, React only changes params in your Class Work, so componentDidMount will not be called again => webpage is not updated! You can add componentDidUpdate to fix this, or put this.handleClick() directly in Render() ( because React will invoke this as you click on another product).

Collapse
 
sirmoustache profile image
SirMoustache

There is another solution with passing location property to your component.

You can check it here here