Home > Software design >  Invalid hooks call - React Native
Invalid hooks call - React Native

Time:02-08

I'm new to react native and implementing a flat list. Inside render item of flat list I'm rendering a functional component and I want to use state to change an image if the user selects or deselects it.

The issue I'm facing is that is throws invalid hooks call. I'm tried all the tutorials but it shows the exact same way for describing the state.

const NewsItem = (props, item, onFavouriteSelect, index) => {

const[isFavourite,setFavourite] = useState(false);

return<Text>Random text for stackoverflow</Text>

}

Flat List Code:

render() {
return (
  <View style={styles.container}>
    {this.state.newsList.length > 0 ? (
      <FlatList
        showsVerticalScrollIndicator={false}
        data={this.state.newsList}
        renderItem={({item, index}) =>
          NewsItem(
            this.props,
            item,
            this.onFavouriteSelect.bind(this),
            index,
            this.state.isFavourite,
          )
        }
      />
    ) : (
      <LoadingScreen />
    )}
  </View>
);
}

Versions of react, react dom and react native are mentioned below:

"react": "17.0.2",
"react-dom": "17.0.2",
"react-native": "0.67.2",

Error it throws is:

Invalid hook call. Hooks can only be called inside of the body of a function component. 
This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

Thank you.

Updated Code:

class HomeScreen extends Component {
state = {
newsList: [],
IdsList: [],
isFavourite: false,
};

isFavouriteItem(index) {
if (this.state.IdsList.indexOf(index) === -1) {
  return false;
} else {
  return true;
}
}

render(){
return(){

 <FlatList
   showsVerticalScrollIndicator={false}
   data={this.state.newsList}
   renderItem={({item, index}) =>
          NewsCell(
            this.props,
            item,
            this.onFavouriteSelect.bind(this),
            index,
            this.isFavouriteItem(index),
            this.state.isFavourite,
          )
        }
      />

      }}

The updated code I've added now works. But is this a good approach?

CodePudding user response:

Instead of calling const[isFavourite,setFavourite] = useState(false); inside NewsItem, call useState in top-level of your function component.

const NewsItem = (props, item, onFavouriteSelect, index) => {

    const[isFavourite,setFavourite] = useState(false); //remove this line and place in top-level of your function

  return<Text>Random text for stackoverflow</Text>

}

Ref : Breaking the Rules of Hooks

CodePudding user response:

Use this way

import NewsItem from './NewsItem';

renderItem={({item, index}) =>
          <NewsItem 
            props={this.props} 
            item={item}
            onFavouriteSelect={this.onFavouriteSelect}
            index={index}
            isFavourite={this.state.isFavourite},
          )
        }


const NewsItem = ({props, item, onFavouriteSelect, index}) => {

  const[isFavourite,setFavourite] = useState(false);

  return<Text>Random text for stackoverflow</Text>

}
export default NewsItem;
  •  Tags:  
  • Related