美文网首页
useReducer

useReducer

作者: Time_Notes | 来源:发表于2023-09-15 01:00 被阅读0次

    Then you can replace useState: useReducer is very similar to useState, but it lets you move the state update logic from event handlers into a single function outside of your component.

    const[tasks,setTasks]=useState(initialTasks);

    with useReducer like so:

    const[tasks,dispatch]=useReducer(tasksReducer, initialTasks);

    The useReducerHook is similar to useState—you must pass it an initial state and it returns a stateful value and a way to set state (in this case, the dispatch function). But it’s a little different.

    The useReducerHook takes two arguments:

    A reducer function

    An initial state

    And it returns:

    A stateful value

    A dispatch function (to “dispatch” user actions to the reducer)


    Extracting State Logic into a Reducer

    Components with many state updates spread across many event handlers can get overwhelming. For these cases, you can consolidate all the state update logic outside your component in a single function, called a reducer.

    Each of its event handlers calls setTasks in order to update the state. As this component grows, so does the amount of state logic sprinkled throughout it. To reduce this complexity and keep all your logic in one easy-to-access place, you can move that state logic into a single function outside your component, called a “reducer”.

    Reducers are a different way to handle state. You can migrate from useState to useReducer in three steps:

    -Move from setting state to dispatching actions.

    -Write a reducer function.

    -Use the reducer from your component.

    Remove all the state setting logic. What you are left with are three event handlers:

    handleAddTask(text) is called when the user presses “Add”.

    handleChangeTask(task) is called when the user toggles a task or presses “Save”.

    handleDeleteTask(taskId) is called when the user presses “Delete”.

    Managing state with reducers is slightly different from directly setting state. Instead of telling React “what to do” by setting state, you specify “what the user just did” by dispatching “actions” from your event handlers. (The state update logic will live elsewhere!) So instead of “settingtasks” via an event handler, you’re dispatching an “added/changed/deleted a task” action. This is more descriptive of the user’s intent.


    const arr=[1,2,3,4,5];

    const sum=arr.reduce(

        (result, number)=>result+number

    );// 1 + 2 + 3 + 4 + 5

    The function you pass to reduce is known as a “reducer”. It takes the result so far and the current item, then it returns the next result. React reducers are an example of the same idea: they take the state so far and the action, and return the next stateIn this way, they accumulate actions over time into state.

    You could even use the reduce()method with an initialState and an array of actions to calculate the final state by passing your reducer function to it:


    To convert from useState to useReducer:

    Dispatch actions from event handlers.

    Write a reducer function that returns the next state for a given state and action.

    Replace useState with useReducer.

    Reducers require you to write a bit more code, but they help with debugging and testing.

    Reducers must be pure.

    Each action describes a single user interaction.


    Writing reducers well 

    Keep these two tips in mind when writing reducers:

    Reducers must be pure. Similar to state updater functions, reducers run during rendering! (Actions are queued until the next render.) This means that reducers must be pure—same inputs always result in the same output. They should not send requests, schedule timeouts, or perform any side effects (operations that impact things outside the component). They should update objects and arrays without mutations.

    Reducers must be pure, so they shouldn’t mutate state

    Each action describes a single user interaction, even if that leads to multiple changes in the data. For example, if a user presses “Reset” on a form with five fields managed by a reducer, it makes more sense to dispatch one reset_form action rather than five separate set_field actions. If you log every action in a reducer, that log should be clear enough for you to reconstruct what interactions or responses happened in what order. This helps with debugging!


    the useState hook does have its limitations. For example, the useState hook may become cumbersome if you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. In these situations they useReducer hook can provide a much better alternative. 

    You can think of the useReducer as a superpower usestate. They useState hook starts with an initial state, but they useReducer hook gets a reducer function in addition to the initial state. This is beneficial because the reducer functions second argument is the action object. This object has multiple type values, and based on each of these types values, you can invoke the dispatch function to perform a specific operation.

    useReducer example

    When to choose useReducer vs useState

    The useState hook is best used on less complex data.

    While it's possible to use any kind of a data structure when working with useState, it's better to use it with primitive data types, such as strings, numbers, or booleans.

    The useReducer hook is best used on more complex data, specifically, arrays or objects.

    While this rule is simple enough, there are situations where you might be working with a simple object and still decide to use the useState hook.

    Such a decision might stem from the simple fact that working with useState can sometimes feel easier than thinking about how the state is controlled when working with useReducer.

    It might help conceptualizing this dilemma as a gradual scale, on the left side of which, there is the useState hook with primitive data types and simple use cases, such as toggling a variable on or off.

    At the end of this spectrum, there is the useReducer hook used to control state of large state-holding objects.

    There's no clear-cut point on this spectrum, at which point you would decide: "If my state object has three or more properties, I'll use the useReducer hook".

    Sometimes such a statement might make sense, and other times it might not.

    What's important to remember is to keep your code simple to understand, collaborate on, contribute to, and build from.

    One negative characteristic of useState is that it often gets hard to maintain as the state gets more complex.

    On the flip side, a negative characteristic of useReducer is that it requires more prep work to begin with. There's more setup involved. However, once this setup is completed, it gets easier to extend the code based on new requirements

    useReducer is suitable for complex data/state transition/business logic

    相关文章

      网友评论

          本文标题:useReducer

          本文链接:https://www.haomeiwen.com/subject/xrwardtx.html