Typescript React 路由需要在另一个组件中声明 Prop

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

我目前正在重构我的应用程序以合并 TypeScript,但我在使用 React Router 时遇到了一些问题。我收到以下错误。

类型“{}”中缺少属性“toggleCreateForm”,但在 输入“FormProps”。

据我所知,这是因为我没有将自定义钩子作为道具传递到 Routes 元素中,但我认为我不应该这样做,因为钩子是在另一个组件中声明并由该状态管理的。我需要复制这个似乎违反直觉。

应用程序.tsx

function App(): React.JSX.Element {
  const [isLoading, setIsLoading] = useState(false);
  const token = useAppSelector(selectToken);
  const currentUser = useAppSelector(selectCurrentUser);
  const isAuthenticated = useAppSelector(selectAuthenticated);
  
  const dispatch = useAppDispatch();
  
  const checkLoggedIn = useCallback(() => {
    setIsLoading(true)
    dispatch(userCheckLoggedIn());
    setIsLoading(false)
  }, [isAuthenticated]);

  useEffect(() => { 
    checkLoggedIn()
  }, [checkLoggedIn])
  
  console.debug(
    "App",
    "currentUser", currentUser,
    "token=", token
  )
    
  // Find current user using local storage "token"

  if (isLoading) {
    return <LoadingComponent/>
  } else {
    if (!(token && isAuthenticated)) {
      return (
        <div className="">
          <NavBar></NavBar>
          <Routes>
            <Route path="/register" element={<SignupForm/>}/>
            <Route path="/" element={<Homepage/>}/>
            <Route path="*" element={<Homepage/>}/>
          </Routes>
        </div>
      )
    } else {
      return (
        <div className="App">
          <NavBar></NavBar>
          <Routes>
            <Route path="/workouts" element={<WorkoutList/>}/>
            <Route path="/workouts/:workout_id" element={<WorkoutDetail/>}/>
            <Route path="/workouts/add" element={<NewWorkoutForm/>}/>
            <Route path="/register" element={<SignupForm/>}/>
            <Route path="/exercises" element={<ExerciseList/>}/>
            <Route path="/exercises/add" element={<NewExerciseForm/>}/>
            <Route path="/account" element={<Account/>}/>
            <Route path="/" element={<Homepage/>}/>
            <Route path="*" element={<NotFound/>}/>
          </Routes>
        </div>
      );
    }
  }
}

export default App;

NewWorkoutForm.tsx

interface FormValues {
  name: string,
  category: number
};

interface Category {
  id: number,
  user_id: number
  name: string,
  systemdefault: boolean
};

interface FormProps{
  toggleCreateForm(): boolean
}

const NewWorkoutForm = ({toggleCreateForm} : FormProps): React.JSX.Element => {
    const dispatch = useAppDispatch();
    const categories = useAppSelector(selectCategories);
    const currentUser = useAppSelector(selectCurrentUser);

    const categoryComponents : object[] = categories.map( (cat : Category) => (
        <option value={cat.id}>{cat.name}</option>
    ))

    return (
        <div className="d-flex justify-content-center">
            <Card className="w-25 d-flex flex-column align-items-center pb-3">
                <h3>New Workout Form</h3>
                <Formik
                    initialValues={{
                        name: '', 
                        category: 1,
                        }}
                    validate={(values: FormValues) => {
                        const errors: FormikErrors<FormValues> = {};
                        if (!values.name){ errors.name = 'Name Required'}
                        return errors
                    }}

                    onSubmit={(values : FormValues, { setSubmitting } : FormikHelpers<FormValues>) => {
                        setTimeout( async () => {
                            dispatch(addWorkout({
                                ...values,
                                user_id: currentUser.id,
                                favorited: false
                            }))
                            setSubmitting(false);
                            toggleCreateForm();
                        }, 400)
                    }}
                    >
                        {({isSubmitting}) => (
                            <div>
                            <Form>
                                <div className="d-flex flex-column align-items-center row-gap-3">    
                                    <div className="d-flex flex-column align-items-between row-gap-3">

                                    <div className="d-flex flex-row justify-content-between">
                                        <label htmlFor="name">Workout Name:</label>
                                        <Field type='name' name='name'/>
                                    </div>
                                    <div style={{color: "red"}}>
                                        <ErrorMessage name='name' component='div'/>
                                </div>
                                    <div className="d-flex flex-row justify-content-between">
                                        <label htmlFor="category">Workout Category:</label>
                                        <Field as='select' name='category'>
                                            {categoryComponents}
                                        </Field>
                                    </div>
                                    <div style={{color: "red"}}>
                                        <ErrorMessage name='category' component='div'/>
                                </div>
                                    </div>
                                    <div className="d-flex flex-row column-gap-5">
                                        <button className="btn btn-danger" onClick={toggleCreateForm}>Cancel</button>
                                        <button className="btn btn-success" type='submit' disabled={isSubmitting}>Create Workout</button>
                                    </div>
                                </div>
                            </Form>
                            </div>
                        )}
                </Formik>
            </Card>
        </div>
    )
}

export default NewWorkoutForm;

toggleCreateForm
是一个自定义钩子,传递到
NewWorkoutForm

const [showCreateWorkoutForm, setShowCreateWorkoutForm] = useToggle();

const toggleCreateForm = () => { 
  setShowCreateWorkoutForm()
}

这是在 TypeScript 之前工作的。

reactjs typescript
1个回答
0
投票

我认为你只需要编辑你的界面,这样就不需要切换功能了

interface FormProps{
  toggleCreateForm?: () => boolean
}
© www.soinside.com 2019 - 2024. All rights reserved.