web-dev-qa-db-ja.com

React Context API-ページの更新時にデータを保持する

いくつかの初期データプロパティ値とともに、コンテキストプロバイダーがセットアップされているとします。

線に沿ったどこかで、消費者がそれらのプロパティを変更したとしましょう。

ページをリロードすると、これらの変更は失われます。データの変更を保持できるようにデータを永続化する最良の方法は何ですか?単なるローカルストレージ以外の方法はありますか?

9
Cog

ええ、データをリロード後も保持したい場合、オプションはその情報をサーバー側(api呼び出し経由)またはブラウザーストレージ(ローカルストレージ、セッションストレージ、Cookie)に保存します。使用するオプションは、達成しようとしている永続性のレベルによって異なります。ストレージの選択に関係なく、おそらく次のようになります。

const MyContext = React.createContext(defaultValue);

class Parent extends React.Component {
  setValue = (value) => {    
    this.setState({ value });
  }

  state = {
    setValue: this.setValue,
    value: localStorage.getItem("parentValueKey")
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.state.value !== prevState.value) {
      // Whatever storage mechanism you end up deciding to use.
      localStorage.setItem("parentValueKey")
    }
  }

  render() {
    return (
      <MyContext.Provider value={this.state}>
        {this.props.children}
      </MyContext.Provider>
    )
  }
}
3
TLadd

コンテキストはあなたが望むように持続しません。 Reactフックでステートレス関数を使用して、私がやったことのサンプルを次に示します。

_import React,  {useState, useEffect} from 'react'

export function sample(){
  // useState React hook
  const [data, setData] = useState({})
  const [moreData, setMoreData] = useState([])

  // useState React hook
  useEffect(() => { 
    setData({test: "sample", user: "some person"})
    setMoreData(["test", "string"])
  }, [])

  return data, moreData
}

export const AppContext = React.createContext()

export const AppProvider = props => (
  <AppContext.Provider value={{ ...sample() }}>
    {props.children}
  </AppContext.Provider>
)

_

最初からこれは回避策であり、永続的な解決策ではないことを理解してください。データの永続化は、クライアントではなくデータベースの仕事です。ただし、開発のために永続データが必要な場合は、これが1つの方法です。最初に React hooks を使用していることに注意してください。これは、16.8から完全にサポートされる機能です。 useEffect()は、上記のTLaddのようなクラス宣言にあるライフサイクルメソッドを置き換えます。彼はcomponentDidUpdateを使用して持続しています。これを行う最新の方法はuseEffectです。アプリが更新されると、このメソッドが呼び出され、ハードコードされたデータがコンテキストに設定されます。

プロバイダーを使用するには:

_import React from 'react'
import Component from './path/to/component'
import { AppProvider } from './path/to/context'

const App = () => {
  return (
    <AppProvider>
      <Component />
    </AppProvider>
  )
}
_

更新すると、datamoreDataには、デフォルト値が割り当てられます。

3