我正在尝试将 React 组件转换为 React 打字稿,但 useContext 和 useReducer 导致我的代码出错。
唯一的区别是我为打字稿格式设置的一些接口。
这是我根据 https://www.youtube.com/watch?v=HERhqPlPyuY 的课程更改的代码 代码链接:https://github.com/rivera1294/react-notes-app
代码在下面
enter code here
import { create } from 'domain';
import { any } from 'prop-types';
import React,{FunctionComponent, useState, useContext, useReducer, createContext, useRef, useEffect} from 'react';
import { updateFunctionDeclaration } from 'typescript';
import {v4 as uuid} from 'uuid'
// import NoteContext from './MemoContext'
// import MemoReducer from './MemoReducer'
interface ContextInitialState{
id : number,
text : string
}
interface ContextProps{
currentNote : any,
notes : ContextInitialState[],
state? : any,
dispatch? : React.Dispatch<any>
}
const initialState:ContextProps = {
currentNote : null,
notes : [
{id : 1, text : 'Do Homework'},
{id : 2, text : 'UnderStand Interface'},
{id : 3, text : 'Do you Get IT?'}
],
}
const NoteContext = createContext<ContextProps>(initialState)
interface MemoState{
notes : ContextInitialState[]
}
interface initialState{
notes : []
}
interface ReducerProps{
state : React.ReactNode,
action : React.ReducerAction<any>
}
//this is reducer
const memoReducer = (state, action) => {
switch(action.type){
case 'SET_CURRENT_NOTE':
return{
...state,
currentNote : action.payload //?
}
case 'DELETE_NOTE':
const deletedNotes = state.notes.filter(
note => note.id !== action.payload
)
return{
...state,
notes : deletedNotes
}
case 'ADD_Note' :
const newNote = {
id : uuid.v4(), //uuid is a library -> gives unique id.
text : action.payload
}
const addedNotes = [...state.notes, newNote]
return{
...state,
notes : addedNotes
}
case 'UPDATE_NOTE' : {
const updatedNote = {
...state.currentNote,
text : action.payload
}
const updatedNoteIndex = state.notes.findIndex(
note => note.id === state.currentNote.id
)
const updatedNotes = [
...state.notes.slice(0, updatedNoteIndex), // grab all the notes upto the index
updatedNote,
...state.notes.slice(updatedNoteIndex + 1)
];
return{
currentNote : null,
notes : updatedNotes
}
}
default:
return state;
}
}
const Nav = () => {
return (
<div>
<p>this is Nav</p>
</div>
)
}
interface AddNoteProps{
state : any,
dispatch? : React.Dispatch<any>,
value : any,
}
const AddNote = () => {
const {state, dispatch} = useContext(NoteContext);
const [value, setValue] = useState('')
let ref:any = useRef();
useEffect(()=>{
ref.current.focus();
},[]) //한번만 실행하길 원해서 배열을 마지막에 넣는다.
const handleChange =(event:any)=> {
setValue(event.target.value)
}
const handleSubmit = (event:any) =>{
event.preventDefault();
if(value.trim()===''){
alert('cannot add a blank memo')
}
else{
dispatch?.({ type : 'ADD_NOTE', payload : value}) //? 이게 뭐람..?
setValue('');
}
}
return (
<div className = "note-form">
<form>
<input type = "text" ref = {ref}/>
<button>Add Notes</button>
</form>
</div>
)
}
interface NoteProps{
note : any,
children? : React.ReactChild,
dispatch? : React.Dispatch<any>
}
const Note:FunctionComponent<NoteProps> = ({note}) => {
const{dispatch } = useContext(NoteContext)
//action area
return (
<div className = "note">
<p>{note}</p>
<div className = "btn-container">
<button className = "edit"
onClick = {()=>dispatch?.({type : 'SET_CURRENT_NOTE', payload : note})}
>Edit</button>
<button className = "delete"
onClick = {()=>dispatch?.({type: 'DELETE_NOTE', payload : note.id})}
>Delete</button>
</div>
</div>
)
}
//useContext, NotesContext from '../context'
const NoteList = () => {
const {state} = useContext(NoteContext)
return(
<div className = "note-container">
{state.notes.map((note, index)=>{
return <Note note = {note} key = {index}/>
})}
</div>
)
}
interface EditNoteProps{
state? : any,
value? : any,
}
const EditNote:FunctionComponent<EditNoteProps> = () =>{
const {state, dispatch } = useContext(NoteContext);
const [value, setValue] = useState()
let ref:any = useRef();
useEffect(()=>{
ref.current.focus();
},[])
const handleChange = (event) =>{
setValue(event.target.value)
}
const handleSubmit = (event) =>{
event.preventDefault();
if(value.trim()===''){
alert('cannot add a blank note')
}
else{
dispatch?.({type : 'UPDATE_NOTE', payload : value})
}
}
return(
<div>
<form onSubmit = {handleSubmit} action = "">
<textarea ref = {ref} onChange = {handleChange} value = {value} name = "" id = "" />
<div>
{/* <p>need to add style here, lesson 5 describes it</p> */}
</div>
</form>
</div>
)
}
interface MeomoViewProps{
value : any,
}
const MemoView:FunctionComponent<MeomoViewProps> = () => {
const initialState = useContext(NoteContext);
const[state, dispatch] = useReducer(memoReducer,initialState)
console.log(state);
return (
//<NoteContext.Provider value = {{state, dispatch}} <-이거였음 원래는
<NoteContext.Provider value = {{state, dispatch}}>
<Nav/>
{state.currentNote === 'null'? (
<div>
<AddNote />
{/* <NoteList/> */}
</div>
) : (
<EditNote value = ""/>
)}
<AddNote />
<NoteList/>
</NoteContext.Provider>
// <div>
// this fucking this is not working
// </div>
);
};
export default MemoView;
ts2739 错误