useReducer
Dažniausiai yra naudojamas useState. useReducer naudojamas, kai state labai sudetingas, pvz objektas.
Parametrai reducer fnc:
- Pirmas parametras
previousName, senas (esamas) steitas - Antras parametras
newName, nauja reiksmė
function nameReducer (previousName: string, newName: string) { return newName } const initialNameValue = 'Joe' function Name Input() { const [name, setName] = useReducer(nameReducer, initialNameValue) const handleChange = event => setName(event.currentTarget.value) return ( <div> <label> Name: <input defaultValue={name} onChange = {handleChange} /> </label> <div>You typed: {name}</div> </div> } }
Parametrai useReducer:
- pirmas parametras funcija darbui su duomenimis
- antras init duomenys
import { useReducer, useState } from 'react' import * as ReactDOM from 'react-dom/client' const countReducer = (count: number, change: number) => count + change function Counter({ initialCount = 0, step = 1 }) { const [count, changeCount] = useReducer(countReducer, initialCount) const increment = () => changeCount (step) const decrement = () => changeCount(-step) return ( <div className="counter"> <output>{count}</output> <div> <button onClick={decrement}></button> <button onClick={increment}></button> </div> </div> ) }
State object
const [state, setState] = useReducer (countReducer, { count: initialCount, }) const { count } = state const increment = () => setState({ count: count + step }) const decrement = () => setState({ count: count - step })
const [state, setState] = useReducer (countReducer, { count: initialCount, someOtherState: 'hello', }) const { count } = state const increment = () => setState({ count: count + step }) const decrement = () => setState({ count: count - step })
Actions function
Kai state didesnis tokiu principu atnaujinant, prarasime dali objekto. Naujas state užrašis ant viršaus, o reikia merdžint
Toks principas neracionalus someOtherState: state. someOtherState, nes keiciantis objektui, reikes visada keisti ir čia.
const {count} = state const increment = () => setState({ count: count + step, someOtherState: state. someOtherState }) const decrement = () => setState( count: count
Paprastas sprendimas
const {count} = state const increment = () => setState({ ... state, count: count + step }) const decrement = () => setState({ ... state, count: count step })
Arba galima mergint reduceryje
const countReducer = (state: State, action: Action) => ({...state, ...action})
Naudosim action functions
Action Function
const [state, setState] = useReducer (count Reducer, { count: initialCount, }) const { count } = state const increment = () => setState(currentState => ({ count: currentState.count + step })) const decrement = () => setState(currentState => ({ count: currentState.count - step }))
Jeigu state priklauso nuo buvusio state, tai reikia naudoti funkcija
setState({ count: count + step })- tokiu atveju pametamnas state (nes settime metu paimtas state ten ir bus naudojamassetState(currentState => ({ count currentState.count - step }))- čia ok, nes naudojamass prev state (bus naujas)
type State = {count: number } type Action = Partial<State> | ((state: State) => Partial<State>) const count Reducer = (state: State, action: Action) => ({ ...state, ...(typeof action === 'function' ? action (state): action), }) function Counter({ initialCount = 0, step = 1 }) { const [state, setState] = use Reducer (count Reducer, { count: initialCount, }) const {count } = state const increment = () => { setTimeout(() => { setState({ count: count + step }) }, 500) } const decrement = () => { setTimeout(() => { setState(currentState => ({ count currentState.count - step })) }, 500) }
Traditional Reducer
Action - reiklaingas type propertry ir nebutinas payload
const [state, dispatch] = useReducer (count Reducer, { count: initialCount, }) const { count } = state const increment = () => dispatch({ type: 'INCREMENT', step }) const decrement = () => dispatch({ type: 'DECREMENT', step })
type Action = { type: 'increment'; step: number } | { type: 'decrement'; step: number }action type aprašymas
type State = { count: number } type Action = { type: 'increment'; step: number } | { type: 'decrement'; step: number } const count Reducer = (state: State, action: Action) => { const { type, step } = action switch (type) { case 'increment': { return { ..state, count: state.count + step, } } case 'decrement': return { ...state, count: state.count step, } }
Dar vienas reducer
type GameAction = { type: 'SELECT_SQUARE'; index: number } | { type: 'SELECT_STEP'; step: number } | { type: 'RESTART' } function gameReducer (state: GameState, action: GameAction) { // your code... }
- skaitosi
lazy initkai tokia realizacija props.initialCount, getInitialState,
function getInitialState (initialCount: number) { return { count: initialCount } } function Counter() { const [count, dispatch] = useReducer( countReducer, props.initialCount, getInitialState, ) // ... }
Reducer pvz:
function game StateReducer(state: GameState, action: GameAction) { switch (action.type) { case 'SELECT_SQUARE':{ const {index} = action const current Squares = state.history[state.currentStep] const winner = calculateWinner(current Squares) if (winner || currentSquares [index]) return state const { currentStep, history } = state const newHistory = history.slice(0, currentStep + 1) const nextValue = calculateNextValue(current Squares) const squares = history[current Step].with(index, nextValue) return { history: [...newHistory, squares], currentStep: newHistory.length, } case 'RESTART': { return defaultState } case 'SELECT_STEP': { const { step } = action return { ... state, currentStep: step, } } default: { break }