响应 React 打字稿迁移问题(useContext,useReducer)

时间:2020-12-22 03:03:32

标签: reactjs typescript interface

我正在尝试将 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;

enter image description here

enter image description here

ts2739 错误

0 个答案:

没有答案