我是使用 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}})
预计: 用户应该添加到状态并在子组件中渲染。
您已将
ContRedContext
输入为可为空,因此消费者需要在访问 state
或 dispatch
之前使用空检查。但您似乎从未传递过 null
上下文值,而且可能也没有必要。
更新
ContRedContext
上下文类型声明以删除 null
类型:
export const ContRedContext = createContext<UserContextType>({
state: initialState,
dispatch: () => {}
});