user13283967
user13283967

Reputation:

How to pass props to FlatList with renderScene in react-native-tab-view?

I'm a newbie in React Native and trying to pass props to ListHeaderComponent in FlatList

Here's the code:

const FirstRoute = (props) => {
  const _renderHeader = () => {
    return(
      <View>
        {props.isFollowed && 
        <TouchableOpacity onPress={props.onSubmit}>
          <Text>You have followed this person</Text>
        </TouchableOpacity> } 
    </View>
    )
  }
  return(
    <View style={[styles.scene, { backgroundColor: '#ff4081' }]}>
    <FlatList
      data={data}
      keyExtractor={item => item.id}
      renderItem={itemData => ( <Image source={itemData.item.id} style={{height: WIDTH/3, width: WIDTH/3}} />)}
      ListHeaderComponent={_renderHeader}
    />
  </View>
  )
};

const SecondRoute = () => (
  <View style={[styles.scene, { backgroundColor: '#673ab7' }]} />
);

const initialLayout = { width: Dimensions.get('window').width };

export default function Parent() {
  const [index, setIndex] = React.useState(0);
  const [routes] = useState([
    { key: 'first', title: 'First' },
    { key: 'second', title: 'Second' },
  ]);
  const [_isFollowed, setIsFollowed] = useState(false);
  const _onSubmit = () => {
    ...
    setIsfollowed(true)

  }

  const renderScene = ({route}) => {
    switch(route.key){
      case 'first': return <FirstRoute {...props} onSubmit={_onSubmit} isFollowed={_isFollowed} />
      case 'second': return <SecondRoute  {...props} />
    }
  };

  return (
    <TabView
      navigationState={{ index, routes }}
      renderScene={renderScene}
      onIndexChange={setIndex}
      initialLayout={initialLayout}
    />
  );
}

But when I save it, the screen logs the error: Can't find the value of isFollowed

I think the problem is at the way I pass the props. I'm still learning it. Since when I delete the ListHeaderComponent, the FlatList still generates the list of images well. And I don't know if it has something to do with renderScene

I really don't understand why

Please help me. Thank you very much

Upvotes: 0

Views: 1631

Answers (1)

edilsonlm217
edilsonlm217

Reputation: 76

Let me get this straight. You need to render _renderHeader dinamically based on _isFollowed state. So, you passed to the first route as props your _onSubmit function and _isFollowed state in order to get to access them at _renderHeader. Right?

As I see you actually doesn't need to do it once your _renderHeader has direct access to both _isFollowed state and _onSubmit function. Try it out as bellow:

export default function Parent() {
  const [index, setIndex] = React.useState(0);
  const [routes] = useState([
    { key: 'first', title: 'First' },
    { key: 'second', title: 'Second' },
  ]);

  const [_isFollowed, setIsFollowed] = useState(false);

  const initialLayout = { width: Dimensions.get('window').width };

  function _onSubmit() {
    setIsFollowed(true);
  }

  function _renderHeader() {
    return (
      <View>
        {_isFollowed && 
        <TouchableOpacity onPress={_onSubmit}>
          <Text>You have followed this person</Text>
        </TouchableOpacity> } 
      </View>
    );
  }

  const FirstRoute = () => {
    return(
      <View style={[styles.scene, { backgroundColor: '#ff4081' }]}>
      <FlatList
        data={data}
        keyExtractor={item => item.id}
        renderItem={itemData => ( <Image source={itemData.item.id} style={{height: WIDTH/3, width: WIDTH/3}} />)}
        ListHeaderComponent={_renderHeader}
      />
    </View>
    )
  };

  const SecondRoute = () => (
    <View style={[styles.scene, { backgroundColor: '#673ab7' }]} />
  );



  const renderScene = ({route}) => {
    switch(route.key){
      case 'first': return <FirstRoute />
      case 'second': return <SecondRoute />
    }
  };

  return (
    <TabView
      navigationState={{ index, routes }}
      renderScene={renderScene}
      onIndexChange={setIndex}
      initialLayout={initialLayout}
    />
  );
}

Other point I don't understand in your code and couldn't check cause I didn't try to run it was the function bellow:

function _renderHeader() {
    return (
      <View>
        {_isFollowed && 
        <TouchableOpacity onPress={_onSubmit}>
          <Text>You have followed this person</Text>
        </TouchableOpacity> } 
      </View>
    );
  }

If you want to render TouchableOpacity just in case _isFollowed is true you should do it using ternary operator like so:

function _renderHeader() {
    return (
        <View>
          {_isFollowed ?  
             <TouchableOpacity onPress={_onSubmit}>
               <Text>You have followed this person</Text>
             </TouchableOpacity> } 
           : <></>
          }
        </View>
    );
}

Upvotes: 0

Related Questions