내가 사용 컨텍스트는 페이지 제목을 저장하는 것을 기본 샘플 프로젝트를 설정,하지만 난 그것을 설정할 때 구성 요소가 다시 렌더링되지 않습니다.
주요 파일 :
Context.js
import React from 'react'
const Context = React.createContext({})
export default Context
AppWrapper.js
import React from 'react'
import App from './App'
import Context from './Context'
function AppWrapper () {
return (
<Context.Provider value={{page: {}}}>
<App />
</Context.Provider>
)
}
export default AppWrapper
App.js
import React, { useContext } from 'react';
import Context from './Context';
import Home from './Home';
function App() {
const { page } = useContext(Context)
return (
<>
<h1>Title: {page.title}</h1>
<Home />
</>
);
}
export default App;
Home.js
import React, { useContext } from 'react'
import Context from './Context'
function Home () {
const { page } = useContext(Context)
page.title = 'Home'
return (
<p>Hello, World!</p>
)
}
export default Home
내가 도대체 뭘 잘못하고있는 겁니까?
에 대한 당신처럼 상황에 맞는 반응 생각 구성 요소, 당신이 값을 업데이트 할 당신이 사용할 필요가 다음을 보여 주면 state
. 당신이있어이 경우 AppWrapper
당신이 상태를 추적 할 필요가 어디 상황에 맞는 업체를 렌더링입니다.
import React, {useContext, useState, useCallback, useEffect} from 'react'
const PageContext = React.createContext({})
function Home() {
const {setPageContext, page} = useContext(PageContext)
// essentially a componentDidMount
useEffect(() => {
if (page.title !== 'Home')
setPageContext({title: 'Home'})
}, [setPageContext])
return <p>Hello, World!</p>
}
function App() {
const {page} = useContext(PageContext)
return (
<>
<h1>Title: {page.title}</h1>
<Home />
</>
)
}
function AppWrapper() {
const [state, setState] = useState({page: {}})
const setPageContext = useCallback(
newState => {
setState({page: {...state.page, ...newState}})
},
[state, setState],
)
const getContextValue = useCallback(
() => ({setPageContext, ...state}),
[state, updateState],
)
return (
<PageContext.Provider value={getContextValue()}>
<App />
</PageContext.Provider>
)
}
편집 - 연결 저장소에서 업데이트 작업 솔루션
나는 그 혼란과 구성 요소의 로컬 상태와 충돌 할 수있는 상황을 통해 setState를 통과 권하고 싶지 않다, 조금 더 구체적으로 몇 가지 이름. 또한 내가 대답에 필요하지 않은 코드의 덩어리를 생략하고있어, 단지 부분은 내가 변경
SRC / AppContext.js
export const updatePageContext = (values = {}) => ({ page: values })
export const updateProductsContext = (values = {}) => ({ products: values })
export const Pages = {
help: 'Help',
home: 'Home',
productsList: 'Products list',
shoppingCart: 'Cart',
}
const AppContext = React.createContext({})
export default AppContext
SRC / AppWrapper.js
const getDefaultState = () => {
// TODO rehydrate from persistent storage (localStorage.getItem(myLastSavedStateKey)) ?
return {
page: { title: 'Home' },
products: {},
}
}
function AppWrapper() {
const [state, setState] = useState(getDefaultState())
// here we only re-create setContext when its dependencies change ([state, setState])
const setContext = useCallback(
updates => {
setState({ ...state, ...updates })
},
[state, setState],
)
// here context value is just returning an object, but only re-creating the object when its dependencies change ([state, setContext])
const getContextValue = useCallback(
() => ({
...state,
setContext,
}),
[state, setContext],
)
return (
<Context.Provider value={getContextValue()}>
...
SRC / App.js
...
import AppContext, { updateProductsContext } from './AppContext'
function App() {
const [openDrawer, setOpenDrawer] = useState(false)
const classes = useStyles()
const {
page: { title },
setContext,
} = useContext(Context)
useEffect(() => {
fetch(...)
.then(...)
.then(items => {
setContext(updateProductsContext({ items }))
})
}, [])
SRC / 구성 요소 / DocumentMeta.js
이것은 당신이 각 뷰의 코드 복잡성 / 중복을 감소 선언 스타일로 페이지의 이름을 업데이트하는 데 사용할 수있는 새로운 구성 요소입니다
import React, { useContext, useEffect } from 'react'
import Context, { updatePageContext } from '../Context'
export default function DocumentMeta({ title }) {
const { page, setContext } = useContext(Context)
useEffect(() => {
if (page.title !== title) {
// TODO use this todo as a marker to also update the actual document title so the browser tab name changes to reflect the current view
setContext(updatePageContext({ title }))
}
}, [title, page, setContext])
return null
}
일명 사용은 같은 것 <DocumentMeta title="Whatever Title I Want Here" />
SRC / 페이지 / Home.js
각 뷰는 이제 단지 DocumentMeta와 페이지 "열거는"대신 컨텍스트를 당겨 수동으로 매번 수행의 제목을 업데이트 할 가져올 필요가있다.
import { Pages } from '../Context'
import DocumentMeta from '../components/DocumentMeta'
function Home() {
return (
<>
<DocumentMeta title={Pages.home} />
<h1>WIP</h1>
</>
)
}
참고 : 다른 페이지는 홈 페이지가 무엇을하고 있는지 복제 할 필요가
이, 나는 성능면에서 더 많은 일을 할 수 캐시에 쓰기 데이터, 깊은 병합에 더 일반적인 도우미를 써서 .. 등을하지 내가 프로덕션 환경에서이 작업을 수행 할 어떻게 기억하지만이 있어야한다 포인트를 시작하는 좋은.