реагировать Войти с использованиемКонтекст использованияРедуктор basi c пример - PullRequest
1 голос
/ 30 января 2020

Я использую Typescript. Я хочу

  • Создать контекст
  • Использовать контекст в маршрутизации
  • Обновлять контекст при входе в систему.

I ' Я следую этому уроку , за исключением того, что Typescript не оправдал моих надежд. См. Ниже

У меня есть это в моем App.tsx

import React from 'react';
import './App.css';

import Login from "./auth/login";
import Home from "./dash/home";
import Header from "./menu";

const initialState = {
  isAuthenticated: false,
  user: null,
  token: null,
};

export const AuthContext = React.createContext(); // <---- This right here complains: 
// Expected 1-2 arguments, but got 0.ts(2554)
// index.d.ts(349, 9): An argument for 'defaultValue' was not provided.

const reducer = (state: any, action: any) => {
  switch (action.type) {
    case "LOGIN":
      return {
        ...state,
        isAuthenticated: true,
        user: action.payload.user,
        token: action.payload.token
      };
    case "LOGOUT":
      localStorage.clear();
      return {
        ...state,
        isAuthenticated: false,
        user: null
      };
    default:
      return state;
  }
};

const App: React.FC = () => {
  const [state, dispatch] = React.useReducer(reducer, initialState);

  return (
    <AuthContext.Provider
      value={{
        state,
        dispatch
      }}
    >
      <Header />
      <div className="App">{!state.isAuthenticated ? <Login /> : <Home />}</div>
    </AuthContext.Provider>
  );
}

export default App;

На моей странице входа, у меня есть это:

import React from "react";
import { useForm } from 'react-hook-form';
import axios from 'axios';
import { AuthContext } from "../App";

export const Login = () => {

  const { dispatch } = React.useContext(AuthContext) // <--- This the right way to do it?
  // Where is the "dispatch" magically coming from?

  const onSubmit = (data: any) => {

    axios.post('http://localhost/api/v1/users/login/', data)
      .then(res => {
        console.log(res);
      })
  }

  return (
    <div className="login-container">
      <!-- assume there's a form here -->
    </div>
  );
};
export default Login;

Итак

  • Что мне указать для "defaultValue"?
  • Как обновить контекст после входа в систему?

РЕДАКТИРОВАТЬ:

Больше контекста (каламбур) того, чего я хочу достичь.

У App.tsx есть <AuthContext.Provider ...> ... </AuthContext.Provider> Если я правильно понимаю, этот Контекст принимает значение state, dispatch и согласно {!state.isAuthenticated ... }, динамически чередуется между <Login /> и <Home/> компонентом.

Этот <AuthContext.Provider/> согласно initialState установлен на isAuthenticated: false

Когда пользователь входит в систему на Компонент входа в систему, мой вопрос: как мне через AuthContext обновить значения в App.tsx, чтобы маршрут изменился?

1 Ответ

2 голосов
/ 30 января 2020

Если вы посмотрите на документы о React.createContext

Аргумент defaultValue только используется, когда компонент не имеет соответствующий провайдер над ним в дереве. Это может быть полезно для тестирования компонентов в отдельности без их переноса. Примечание. Передача undefined в качестве значения поставщика не приводит к использованию defaultValue.

потребляющими компонентами. Таким образом, вам не нужно ничего передавать контексту, но вы получаете ошибку, потому что машинописи.

Вам необходимо создать интерфейс для значения контекста.

Вы передаете контекст как

value={{
    state,
    dispatch
}}

Но вам нужно иметь интерфейс для этого при создании context.

export const AuthContext = React.createContext(); // <---- missing interface

Вот пример о том, как это сделать.


Откуда волшебным образом происходит "отправка"?

Так работает useContext.

Значение, которое вы получаете из формы useContext(MyContex) - это значение, переданное MyContext.Provider value prop.

например

<MyContext.Provider value={fooValue}>
    {/* ... */}
</MyContext.Provider>

// same fooValue from the Provider
const fooValue = useState(MyContext)

Edit

После асинхронного c вызова внутри onSubmit вы должны вызвать dispatch и передать {type: 'LOGIN', payload: DATA_FROM_API}, как в методе редуктора, и установить isAuthenticated в true

const onSubmit = (data: any) => {
  axios.post('http://localhost/api/v1/users/login/', data)
    .then(res => {        
      console.log(res.data) // <= if this is `payload`, than pass it to dispatch
      dispatch({type: 'LOGIN', payload: res.data})
    })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...