Search code examples
react-nativereact-native-video

Custom Play/Pause Button with React Native Video - Getting JSON Value Error Message


I'm trying to implement play/pause when pressing the entire video.

const RenderItem = (props) => {
  const [paused, setPaused] = useState(true);
  return (
    <View>
      {props.is_video ? (
        <>
          <Video
            paused={paused}
            resizeMode="contain"
            source={{
              uri: props.mediaUrl,
            }}
          />
          <TouchableWithoutFeedback onPress={setPaused}>
            <Text>Play Darnit!</Text>
          </TouchableWithoutFeedback>
        </>
      ) : (
        <Image
          resizeMode="contain"
          source={{uri: props.mediaUrl}}
        />
      )}
    </View>
  );
};

It seems like pressing the text causes the video to play (I can hear sound), and then it quickly get an error message after:

JSON value '{
    "_dispatchInstances" = "<null>";
    "_dispatchListeners" = "<null>";
    "_targetInst" = "<null>";
    bubbles = "<null>";
    cancelable = "<null>";
    defaultPrevented = "<null>";
    dispatchConfig = "<null>";
    eventPhase = "<null>";
    isTrusted = "<null>";
    nativeEvent = "<null>";
    target = "<null>";
    type = "<null>";
}' of type NSMutableDictionary cannot be converted to BOOL

Also, just to mention, this RenderItem is being rendered within a FlatList where there's multiple videos. I'm not sure if I have to also match the button to the right video? So the play button won't accidentatly play another video, or play all videos at once.

Why am I getting this error?


Solution

  • Your onPress is just calling setPaused, but you're not telling it what to set it to. So at the moment it's just going to feed in the native event from the tap. and then politely tell you that said native event isn't a boolean.

    So if I were you I'd make a function called togglePaused which toggles your state, and then call that in the onPress, like...

    const RenderItem = (props) => {
      const [paused, setPaused] = useState(true);
    
      const togglePaused = () => setPaused(prev => !prev) // add this toggle function
    
      return (
        <View>
          {props.is_video ? (
            <>
              <Video
                paused={paused}
                resizeMode="contain"
                source={{
                  uri: props.mediaUrl,
                }}
                />
                {/* call togglePaused in the onPress prop  */}
              <TouchableWithoutFeedback onPress={togglePaused}>
                <Text>Play Darnit!</Text>
              </TouchableWithoutFeedback>
            </>
          ) : (
            <Image
              resizeMode="contain"
              source={{uri: props.mediaUrl}}
            />
          )}
        </View>
      );
    };