React의 전체 상태 관리(Redux 없음)

62608 단어 react

동기

App 어셈블리 및 이 하위 레벨:

            <Counterss name={name1} liftUp={catch1}/>
Counterss 어셈블리에는 다음 하위 레벨이 있습니다.

        <Counters liftUp={catch1} name={name+'-'+name1}/>
        <Counters liftUp={catch2} name={name+'-'+name2}/>
Counters 어셈블리에는 다음 하위 레벨이 있습니다.

            <Counter liftUp={catch1}
            name={name+'-'+name1}/>
            <Counter liftUp={catch2}
            name={name+'-'+name2}/>
나는 이것을 원한다.

그렇습니다. 저는 제 주를 완전히 통제하고 싶습니다.나는 모든 구성 요소에 useReducer을 사용하여 정의된 국부 상태가 있기를 바란다. 나는 store의 대상이 있기를 바란다. 그 중에서 나는 모든 구성 요소의 모든 국부 상태에 접근할 수 있다. App 구성 요소부터 가장 안쪽 구성 요소, 응용 프로그램의 어느 위치, 어떤 구성 요소 중, 가장 바깥에서 가장 안쪽까지.
나는 응용 프로그램 구성 요소의 일부 상태인 useContextstore을 어디에서나 사용할 수 있도록 dispatch의 대상에 접근하고 싶다. 나는 그것이 수동적이기를 바란다.
이를 위해, 나는 구성 요소를 명명해야 한다. 즉, 프로그램에서 모든 구성 요소를 사용할 때, 나는 state이라는 속성을 모든 구성 요소에 전달해야 한다.
그 밖에 본고에서 찾아야 할 내용은 모든 정보, 즉 국부 상태의 namestate을 향상시키고 dispatch을 사용하여 store 구성 요소에 정의된 App 대상을 통해 모든 구성 요소가 접근할 수 있도록 하는 정책이기 때문이다.

HOC


내가 사용할 HOC는 위의 게시물에 정의된 변형입니다.하나의 구성 요소가 여러 개의 하위 구성 요소를 가질 수 있기 때문에 나는 모든 하위 구성 요소에 대한 모든 정보를 얻을 흥미가 있기 때문에 HOC에 대한 정의는 다음과 같다.
import React,{useState,useRef} from 'react'

export default C=>(props)=>{
    const [foo,setFoo]=useState(0)
    const info1=useRef(null)
    const catch1=(info)=>{
        info1.current=info
        setFoo(prev=>prev+1)
    }
    const info2=useRef(null)
    const catch2=(info)=>{
        info2.current=info
        setFoo(prev=>prev+1)
    }
    const info3=useRef(null)
    const catch3=(info)=>{
        info3.current=info
        setFoo(prev=>prev+1)
    }
    const info4=useRef(null)
    const catch4=(info)=>{
        info4.current=info
        setFoo(prev=>prev+1)
    }
    const info5=useRef(null)
    const catch5=(info)=>{
        info5.current=info
        setFoo(prev=>prev+1)
    }
    const info6=useRef(null)
    const catch6=(info)=>{
        info6.current=info
        setFoo(prev=>prev+1)
    }
    const info7=useRef(null)
    const catch7=(info)=>{
        info7.current=info
        setFoo(prev=>prev+1)
    }
    const info8=useRef(null)
    const catch8=(info)=>{
        info8.current=info
        setFoo(prev=>prev+1)
    }
    const info9=useRef(null)
    const catch9=(info)=>{
        info9.current=info
        setFoo(prev=>prev+1)
    }
    const info10=useRef(null)
    const catch10=(info)=>{
        info10.current=info
        setFoo(prev=>prev+1)
    }
    return (
        <C 
        catch1={catch1} 
        catch2={catch2} 
        catch3={catch3} 
        catch4={catch4}
        catch5={catch5} 
        catch6={catch6}
        catch7={catch7} 
        catch8={catch8} 
        catch9={catch9} 
        catch10={catch10} 
        info1={info1} 
        info2={info2} 
        info3={info3} 
        info4={info4} 
        info5={info5} 
        info6={info6} 
        info7={info7} 
        info8={info8} 
        info9={info9} 
        info10={info10}
        {...props}/>
    )
}
이 HOC를 사용하면 모든 구성 요소에 최대 10명의 아이가 있을 수 있습니다.만약 구성 요소가 10개가 넘는다면, 더 많은 아이들에게서 정보를 얻을 수 있도록 HOC를 수정해야 합니다.

가장 안쪽 구성 요소


가장 안쪽 구성 요소의 정의를 살펴보겠습니다.
import React,{useEffect,useReducer,useContext} from 'react'
import {reducer,initialState} from './reducer'
import {StoreContext} from '../App'

const Counter=({liftUp,name})=>{
    const names=name.split('-')
    const store=useContext(StoreContext)

    const [state,dispatch]=useReducer(reducer,initialState)

    useEffect(()=>{
        liftUp.bind(null,{state,dispatch})()
    },[state])

    return (
        <div>
            {store[names[0]]&&store[names[0]][names[1]]&&
            store[names[0]][names[1]][names[2]].state.counter}
        </div>
    )
}

export default Counter
보시다시피 이것은 useContextstate 함수를 정의했기 때문에 계수기 구성 요소입니다. 아래와 같습니다.
import {INCREMENT,DECREMENT} from './actions'

export const initialState={
    counter:0
}

const increment=(state,action)=>{
    return {
        ...state,
        counter:state.counter+1
    }
}

const decrement=(state,action)=>{
    return {
        ...state,
        counter:state.counter-1
    }
}

export const reducer=(state,action)=>{
    switch(action.type){
        case INCREMENT:
            return increment(state,action)
        case DECREMENT:
            return decrement(state,action)
        default:
            return state
    }
}
당신들은 우리가 dispatch을 0의 초기 상태로 설정한 후에 계수기에 대해 점차적으로 증가하고 점차적으로 감소하는 조작을 하는 것을 볼 수 있습니다.counter 구성 요소는 Counter 속성을 수신합니다.이것은 정보를 liftUp까지 향상시키는 부모 구성 요소에 사용됩니다.Counter 갈고리에서 이렇게 하면 우리가 추가하고자 하는 정보를 포함하는 대상을 useEffect 함수에 귀속시켜 호출합니다.

    useEffect(()=>{
        liftUp.bind(null,{state,dispatch})()
    },[state])

구성 요소 향상


이제 Counters 구성 요소의 정의, Counters 구성 요소의 부모 구성 요소, 또는 최소한 Counter 구성 요소가 하위 구성 요소로 되어 있는지 살펴보겠습니다.
import React,{useReducer,useState,useRef,useEffect,useContext} from 'react'
import Counter from '../Counter'
import * as styles from './index.module.css'
import * as counterActions from '../Counter/actions'
import {reducer,initialState} from './reducer'
import {StoreContext} from '../App'
import withLiftUp from '../../hocs/withLiftUp'

const Counters=({liftUp,name,catch1,catch2,info1,info2})=>{
    const names=name.split('-')
    const store=useContext(StoreContext)
    const [state,dispatch]=useReducer(reducer,initialState)

    const increment1=()=>{
        console.log(store)
        store[names[0]][names[1]][name1].dispatch(counterActions.increment())
    }
    const decrement1=()=>{
        store[names[0]][names[1]][name1].dispatch(counterActions.decrement())
    }

    const increment2=()=>{
        store[names[0]][names[1]][name2].dispatch(counterActions.increment())
    }
    const decrement2=()=>{
        store[names[0]][names[1]][name2].dispatch(counterActions.decrement())
    }

    const name1='counter1'
    const name2='counter2'

    useEffect(()=>{
        liftUp.bind(null,{
            state,dispatch,[name1]:info1.current,[name2]:info2.current
        })()
    },[state,info1.current,info2.current])

    return (
                <div>
            <Counter liftUp={catch1}
            name={name+'-'+name1}/>
            <Counter liftUp={catch2}
            name={name+'-'+name2}/>
            <div>
                <button onClick={increment1}>increment</button><br/>
                <button onClick={decrement1}>decrement</button><br/>
                {store[names[0]]&&store[names[0]][names[1]]&&
                store[names[0]][names[1]][name1]&&store[names[0]][names[1]][name1].state.counter}
            </div>
            <div>
                <button onClick={increment2}>increment</button><br/>
                <button onClick={decrement2}>decrement</button><br/>
                {store[names[0]]&&store[names[0]][names[1]]&&
                store[names[0]][names[1]][name2]&&store[names[0]][names[1]][name2].state.counter}
            </div>
        </div>
    )
}

export default withLiftUp(Counters)
우리가 먼저 주의한 것은 우리가 받은 Counter, catch1, catch2info1의 부동산이다.
const Counters=({liftUp,name,catch1,catch2,info1,info2})=>{
이것은 우리가 앞에서 정의한 info2 HOC를 사용했기 때문이다. 그리고 우리는 이 구성 요소에 서브구성 요소를 만들어야 하기 때문이다. 그 중에서 우리가 정보를 얻으려면 다음과 같다.
            <Counter liftUp={catch1}
            name={name+'-'+name1}/>
            <Counter liftUp={catch2}
            name={name+'-'+name2}/>
withLiftUp이라는 속성과 HOC가 제공한 liftUpcatch1 함수를 아이들에게 어떻게 전달하는지 보실 수 있습니다.
그리고 우리는 다음과 같다.
    const name1='counter1'
    const name2='counter2'

    useEffect(()=>{
        liftUp.bind(null,{
            state,dispatch,[name1]:info1.current,[name2]:info2.current
        })()
    },[state,info1.current,info2.current])
우리는 지금 아이들의 메시지를 전달하고 있다.아이들의 정보는 catch2info1.current에 포함될 것이다. info2.currentinfo1은 참고 문헌이기 때문이다.만약 잘 모르신다면 앞에서 언급한 게시물을 보십시오.
지금 이 이름들을 주의하지 마세요.우리는 그 나무를 가로질러 위로 올라가고 있다.잠시 후, 우리는 계속 아래를 보고, 이 이름들을 고려할 것이다.

info2 구성 요소


이 구성 요소에는 Counterss 구성 요소의 하위 인스턴스가 있습니다.
import React,{useReducer,useContext,useEffect} from 'react'
import Counters from '../Counters'
import {reducer,initialState} from './reducer'
import withLiftUp from '../../hocs/withLiftUp'
import {StoreContext} from '../App'

const Counterss=({catch1,catch2,info1,info2,name,liftUp})=>{
    const names=name.split('-')
    const store=useContext(StoreContext)
    const [state,dispatch]=useReducer(reducer,initialState)

    const name1='counters1'
    const name2='counters2'

    useEffect(()=>{
        liftUp.bind(null,{state,dispatch,
        [name1]:info1.current,[name2]:info2.current})()
    },[state,dispatch,info1.current,info2.current])

    return (
        <div>
        <Counters liftUp={catch1} name={name+'-'+name1}/>
        <Counters liftUp={catch2} name={name+'-'+name2}/>
        {store[names[0]]&&
        store[names[0]][name1]&&store[names[0]][name1].counter1.state.counter}
        {store[names[0]]&&
        store[names[0]][name1]&&store[names[0]][name1].counter2.state.counter}
        {store[names[0]]&&
        store[names[0]][name2]&&store[names[0]][name2].counter1.state.counter}
        {store[names[0]]&&
        store[names[0]][name2]&&store[names[0]][name2].counter2.state.counter}
        </div>
    )
}

export default withLiftUp(Counterss)
당신은 우리가 어떻게 이 도구들을 받았는지 알아차렸습니다.
const Counterss=({catch1,catch2,info1,info2,name,liftUp})=>{
그것은 우리가 아이가 두 명 있기 때문이다.

        <Counters liftUp={catch1} name={name+'-'+name1}/>
        <Counters liftUp={catch2} name={name+'-'+name2}/>
이름도 주의해야 합니다. Counters 아이템을 받았습니다. 우리는 각 하위 항목에 name 아이템을 정의했습니다. 그 중에서 namename1은 구성 요소에 정의됩니다.

    const name1='counters1'
    const name2='counters2'
우리는 항상 name2 갈고리와 도구로 수신한 useEffect 함수를 사용하여 정보를 전달합니다.

    useEffect(()=>{
        liftUp.bind(null,{state,dispatch,
        [name1]:info1.current,[name2]:info2.current})()
    },[state,dispatch,info1.current,info2.current])

구성 요소 향상


마지막으로, 우리는 최상위 구성 요소, App 구성 요소를 얻었다.정의는 다음과 같습니다.
import React,{createContext,useState,useEffect,useReducer} from 'react'
import * as classes from './index.module.css'
import Counterss from '../Counterss'
import withLiftUp from '../../hocs/withLiftUp'
import {reducer,initialState} from './reducer'

export const StoreContext=createContext()

const App=({catch1,info1})=>{
    const [store,setStore]=useState({})
    const [state,dispatch]=useReducer(reducer,initialState)

    useEffect(()=>{
        setStore({state,dispatch,[name1]:info1.current})
    },[state,dispatch,info1.current])

    const name1='counterss1'

    return (
    <StoreContext.Provider value={store}>
        <div className={classes.general}>
            <Counterss name={name1} liftUp={catch1}/>
        </div>
    </StoreContext.Provider>
    )
}

export default withLiftUp(App)
먼저 App에서 createContext의 컨텍스트를 만듭니다.

export const StoreContext=createContext()
또한 react 갈고리를 사용하여 store 객체와 setStore 함수를 만들었습니다.
const [store,setStore]=useState({})
우리는 useState 갈고리에 다음과 같이 설정합니다.

    useEffect(()=>{
        setStore({state,dispatch,[name1]:info1.current})
    },[state,dispatch,info1.current])
useEffect은 HOC 사용으로부터 받은 아이템입니다.
const App=({catch1,info1})=>{
info1도 받았습니다.

            <Counterss name={name1} liftUp={catch1}/>
catch1은 다음과 같이 정의합니다.

    const name1='counterss1'

결론


Readux 없이 React에서 상태 관리를 완전히 제어하는 방법입니다.
이것이 바로 실행 중인 응용 프로그램입니다.

그렇게 복잡하거나 번거롭지 않은 프로그램으로 직접 해 보세요.

좋은 웹페이지 즐겨찾기