【问题标题】:How to properly use useReducer with useContext?如何正确使用 useReducer 和 useContext?
【发布时间】:2019-12-05 10:18:47
【问题描述】:

我一直在尝试将我的 reducer 与我的 Context 提供程序保存在同一个文件中。但是,我无法弄清楚如何在组件文件中使用它。

在我的 Context 函数内部:

const reducer = (state, action) => {
        switch (action.type) {
            case "SET_LOCATION":
                return {...state, location: action.payload}
            case "SET_BUSINESS":
                return {...state, business: action.payload}
            case "SET_DATE":
                return {...state, date: action.payload}
            default:
                return state
            }
    }

const [{location, business, date}, dispatch] = useReducer(reducer, {
        location: "",
        business: "",
        date: "today",
    })

return (
        <ThemeContext.Provider value={{location, business, date, dispatch, reducer}}>
            {props.children}
        </ThemeContext.Provider>
    )

在组件中,在表单内部: 我怀疑我没有正确使用调度,但无法通过谷歌搜索解决它

const {location, business, date, dispatch, reducer} = useContext(ThemeContext)

     return (
              <form className="booking-form">
                <h1>Book a service</h1>
                <label>
                    Location
                <input 
                    type="text" 
                    name="location"
                    value={location} 
                    onChange={() => dispatch("SET_LOCATION")}    
                />
                </label>
                <br/>
                <br/>
                <label> 
                    Business
                <input 
                    type="text" 
                    name="business"
                    value={business}
                    onChange={() => dispatch("SET_BUSINESS")}
                />
                </label>
                    <h2 className="date">Date</h2>
                <label>
                <input 
                    type="radio"
                    name="date" 
                    value="today"
                    checked={date === "today"}
                    onChange={() => dispatch("SET_DATE")}
                />
                    Today
                </label>
                <label>
                <input 
                    type="radio"
                    name="date" 
                    value="tomorrow"
                    checked={date === "tomorrow"}
                    onChange={() => dispatch("SET_DATE")}
                />
                    Tomorrow
                </label>
                <label>
                <input 
                    type="radio"
                    name="date" 
                    value="other"
                    checked={date === "other"}
                    onChange={() => dispatch("SET_DATE")}
                />
                    Different date
                </label>
                {date === "other" ? <Calendar/> : <TimeGrid/>}
            </form>

【问题讨论】:

  • (e) => dispatch("SET_BUSINESS", e.target.value) //在这里发送payload,即e.target.value

标签: javascript reactjs react-hooks use-reducer


【解决方案1】:

你的 reducer 期望收到一个字段为 type 的对象:

const reducer = (state, action) => {
  switch (action.type) {
  // we're checking field type here
  ...
}

但你传递的只是字符串:

() => dispatch("SET_DATE")

您需要调度一个具有预期结构的操作对象,因为您的 reducer 将接收 dispatch() 方法的参数作为第二个参数:

() => dispatch({ type: 'SET_DATE', payload: ... })

你还需要提供一些有效载荷,因为你的 reducer 期望它:

const reducer = (state, action) => {
  return {...state, date: action.payload}
  // here we expect payload field on action object
}

还有一个改进 - 请从组件中提取你的 reducer,因为它有点像静态纯函数。

【讨论】:

  • 我究竟提供了什么有效载荷?
  • 如果需要用户输入的输入,如何提供有效载荷?
  • 作为有效负载,您需要提供减速器正在使用的值。例如,对于 SET_DATE 操作,您需要提供一些内容以放入您所在州的 date 字段中。我可以从您的代码中了解到,您需要根据选择的单选按钮提供"today""tomorrow""other" 字符串。例如,对于第一台收音机,您应该使用 dispatch({ type: 'SET_DATE', payload: 'today' })
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 2022-01-24
  • 2019-12-09
  • 2019-12-15
  • 2023-02-09
相关资源
最近更新 更多