実現したいこと

親のコンポネント内で定義されている状態変数を別ファイルからuseContextを使って変更したい。

具体例

今回は、簡素な例ですがモーダルの出現と消滅を状態変数で管理している場合を考えます。具体的には、App.js内でuseStateを用いて定義された状態変数をCustomedModal.js側で書き換えたいと思います。

ファイルとフォルダの配置

root/
┣ App.js
┣ShowModalContext.js
┗ component/
  ┗ CustomedModal.js

プログラム

解説

  • ShoModalContext.js

ここではcreateContextを用いてcontextで参照するデフォルトの値を設定しています。

import { createContext } from 'react';

export const ShowModalContext = createContext({});
  • App.js

ShoModalContext.jsで定めた変数を呼び出し、<コンテキスト.Provider value={子コンポーネントに渡したい値}>とすることで子コンポーネントからも状態変数の参照を行えます。

import React, { useEffect, useState } from 'react';
import { StyleSheet, Pressable, Text, View } from 'react-native';
import CustomedModal from './component/CustomedModal';
import { ShowModalContext } from './ShowModalContext';

export default function App() {
  const [showModalVisible, setModalVisibility] = useState(false);

  const value = {
    showModalVisible,
    setModalVisibility,
  };

  const showModal = () => {
    setModalVisibility(true);
  };

  return (
    <>
      <View style={styles.centeredView}>
        <Pressable style={styles.button} onPress={showModal}>
          <Text>Show Modal</Text>
        </Pressable>
      </View>
      {showModalVisible && (
        <ShowModalContext.Provider value={value}>
          <CustomedModal />
        </ShowModalContext.Provider>
      )}
    </>
  );
}

const styles = StyleSheet.create({
  centeredView: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  button: {
    borderRadius: 20,
    padding: 10,
    elevation: 2,
    backgroundColor: 'tomato',
  },
});
  • CustomedModal.js

そして今回の子コンポーネントであるこのファイルではShowModalContextを呼び出し、useContextを用いることで状態変数をそのまま弄ることができるようになります。1

import React, { useContext } from 'react';
import { Text, View, Button, StyleSheet, Modal, Pressable } from 'react-native';
import { ShowModalContext } from '../ShowModalContext';

export default function CustomedModal(props) {
  const context = useContext(ShowModalContext);

  const closeModal = () => {
    context.setModalVisibility(!context.showModalVisible);
  };

  return (
    <Modal animationType="none" transparent={true} onRequestClose={closeModal}>
        <Pressable
          style={styles.button}
          onPress={closeModal}>
          <Text style={styles.textStyle}>Hide Modal</Text>
        </Pressable>
    </Modal>
  );
}

const styles = StyleSheet.create({
  centeredView: {
    justifyContent: 'center',
    alignItems: 'center',
  },
  button: {
    borderRadius: 20,
    padding: 10,
    elevation: 2,
    backgroundColor: '#F194FF',
  },
});

最後に

ReactでuseContextを使う例はggると沢山出てくるのですが、React NativeでuseContextを使う例の解説が無かったので説明しておきました。

今回のように、アプリ全体でグローバルに状態を維持する必要はないけど子コンポーネントでもちょこっと状態を弄りたいという場合に便利ですね。


  1. 念のための説明ですが、const { showModalVisible, setModalVisibility } = useContext(ShowModalContext);という書き方もできます。 ↩︎