lc74
lc74

Reputation: 134

React componentDidMount confusion

I'm confused by some behavior and wondering if someone can help. I have a React component which fetches movie data depending on the filter passed in through props. Using console.log I can see that my componentDidMount() is only being called once, yet each time the component is re-rendered due to receiving different props a state variable that is only set in componentDidMount() changes. My code is quite long so I don't want to post it all but I can if needed. The snippet that is causing my confusion is below:

class MoviesList extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
                        filterList : [], filter: {}
        };
    }
    async componentDidMount() {
        console.log("shouldOnlyCallOnce");
        if( this.props.filter.on) {
            if (this.props.filter.type == "title"){
                try {
                    const url = "mycustomapi.com/api/"+this.props.filter.title;
                    const response = await fetch(url);
                    const jsonData = await response.json();
                    jsonData.sort((a, b) => a.title.localeCompare(b.title));
                    console.log("??");
                    this.setState({filterList: jsonData, filter: this.props.filter});
                }
                catch (error) {
                    console.error(error);
                }
            }

Despite the state.filter only being set there in the whole component, it changes each time my component is reloaded. Does anyone know how this could happen without console logging multiple times?

Upvotes: 0

Views: 42

Answers (2)

Pankaj Pramanik
Pankaj Pramanik

Reputation: 63

ComponentDidMount will trigger when a component will do intiate render. After a props or state change, ComponentDidUpdate will trigger .Please check the link : react life cycle example

Upvotes: 0

Viktor W
Viktor W

Reputation: 1149

As I see it, the only explanation is that you are modifying the contents of the filter outside this component.

Consider this:

let filterA = { title: 'foo' }

let filterB = filterA
console.log(filterB.title) // Shows 'foo'

filterA.title = 'bar'
console.log(filterB.title) // Shows 'bar'

Even though we never directly modified filterB here, the value changed. This is because filterA and filterB are referencing the same object, so of course they both change.

If you in your case pass the filter as a prop, and later modify the filter inside the parent, the filter will have changed in the child as well.

As a side note: What you are doing is called deriving state from props, which means that you are using the props to set the state. This is almost never good practice. https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html

Upvotes: 1

Related Questions