打字稿问题和减速器状态不会增加点击时的使用。类型“UserContextType | ”上不存在属性“状态和调度”空'

问题描述 投票:0回答:1

我是使用 React 的打字稿新手,尝试了很多东西但不起作用。状态不起作用并出现打字稿错误属性“状态和调度”在类型“UserContextType |”上不存在无效的' UserContRed.tsx

export const UserContRed = () => {

   //const context = useContext(ContRedContext)
    const {state , dispatch } = useContext(ContRedContext)
   
    const [firstname, setFirstname] = useState('')
    const [id, setId ] = useState(0)
    const [lastname, setLastname] = useState('')
 
    // let displayUsers =  context?.state.users.map( (u:any) => {
    let displayUsers =  state.users.map( (u:any) => {
        return(
            <ul key={u.id}>
                <li>{u.id}</li>
                <li>{u.firstname}</li>
                <li>{u.lastname}</li>
            </ul>
        ) 
    }) 
    const addUser = () => {
        const addUser = () => dispatch({type:ActionType.ADD, payload : {id:1,firstname:firstname, lastname:lastname}})
    }

    return(
        <div>
          <div>
            <label>Id: </label>
            <input type="text" onChange={(e)=>{setId(Number(e.target.value))}} />
          </div>
          <div>
            <label>Firstname: </label>
            <input type="text" onChange={(e)=>{setFirstname(e.target.value)}} />
          </div>
          <div>
            <label>Lastname: </label>
            <input type="text" onChange={(e)=>{setLastname(e.target.value)}} />
          </div>
            <button onClick={addUser}>sendToStore</button>

          
        </div>
       
    )
}

ContRed.tsx


export type User = {
    id: number;
    firstname: string;
    lastname: string; 
}

type contredProps = {
    children: React.ReactNode
}


export type IuserState = {
    users : User[]
}
const initialState: IuserState = {
    users : [
        {
            id:0,
            firstname:'',
            lastname: ''
        }
    ]
}
export enum ActionType {
    ADD="add",
    REMOVE="remove"
}


type  userAction = {
    type: ActionType,
    payload: User
}


export const reducer = (state: IuserState, action: userAction) : typeof initialState  => {
    
    switch(action.type){
        case "add": 
                return ({...state, users: [...state.users,
                                                    {id:action.payload.id,
                                                     firstname:action.payload.firstname,
                                                     lastname:action.payload.lastname   
                                                    }
                                                ]
                        })
        case "remove": 
                        return ({...state, users: [
                                    ...state.users.filter(data => data.id !== action.payload.id)]
                                })
        default:
            return state;
    }
}


type UserContextType = {
    state: IuserState
    dispatch: React.Dispatch<userAction>
}

export const ContRedContext = createContext<UserContextType|null>({
    state:initialState,
    dispatch: () => {}
})



export const ContRedContextProvier = ({children}:contredProps) => {
    
    const[state,dispatch] = useReducer(reducer,initialState as IuserState);
    const value : UserContextType = { state, dispatch}
    
    return(
        <ContRedContext.Provider value={value}>
            {children}
        </ContRedContext.Provider>
    )

}

App.tsx

    <ContRedContextProvier>
        <UserContRed/>
    </ContRedContextProvier>
    

我尝试使用常量而不是解构打字稿错误消失,但它没有添加或不更新状态。在我看来,打字稿很难反应,请解释或指导我做错了什么。 下面尝试的打字稿很好,但功能不起作用

  const context = useContext(ContRedContext)
  let displayUsers =  context?.state.users.map( (u:any) => { ...}
   const addUser = () => context?.state.dispatch({type:ActionType.ADD, payload : {id:1,firstname:firstname, lastname:lastname}})

尝试过:

 const context = useContext(ContRedContext)
  let displayUsers =  context?.state.users.map( (u:any) => { ...}
   const addUser = () => context?.state.dispatch({type:ActionType.ADD, payload : {id:1,firstname:firstname, lastname:lastname}})

预计: 用户应该添加到状态并在子组件中渲染。

reactjs typescript react-hooks
1个回答
0
投票

您已将

ContRedContext
输入为可为空,因此消费者需要在访问
state
dispatch
之前使用空检查。但您似乎从未传递过
null
上下文值,而且可能也没有必要。

更新

ContRedContext
上下文类型声明以删除
null
类型:

export const ContRedContext = createContext<UserContextType>({
  state: initialState,
  dispatch: () => {}
});
© www.soinside.com 2019 - 2024. All rights reserved.