Architektura aplikacji w React.js

Architektura aplikacji w React.js

Czyli poszukiwania świętego graala.

Jak zaprojektować strukturę plików w aplikacji reactowej?
Co z routingiem? Autoryzacja i uwierzytelnianie?
Redux? Rest API?

85977ebfe59c2ee669f2196930f1a701?s=128

Michał Taszycki

August 31, 2019
Tweet

Transcript

  1. 2.
  2. 3.
  3. 4.
  4. 5.
  5. 6.
  6. 7.
  7. 8.
  8. 9.
  9. 10.
  10. 11.
  11. 12.

    OK.

  12. 20.
  13. 21.
  14. 22.
  15. 23.
  16. 24.
  17. 25.

  18. 32.

    index.js styles.css <App /> <TodoList /> <Todo /> <AddTodoForm />

    .App {…}; .TodoList {…}; .Todo {…}; .AddTodoForm {…};
  19. 42.

    index.js components/ styles/ __tests__/ utilities/ main.scss App.scss TodoList.scss Todo.scss AddTodoForm.scss

    @import “App.scss” @import “TodoList.scss” @import “Todo.js” @import “AddTodoForm.scss”
  20. 43.

    index.js components/ styles/ __tests__/ utilities/ main.scss App.scss TodoList.scss Todo.scss AddTodoForm.scss

    @import “App.scss” @import “TodoList.scss” @import “Todo.js” @import “AddTodoForm.scss”
  21. 64.
  22. 74.

    index.js components/ App/ index.js App.js App.test.js App.scss Todo/ utilities/ import

    App from “components/App” LEPIEJ import App from “./App” export default App;
  23. 77.

    index.js components/ App/ package.json App.js App.test.js App.scss Todo/ utilities/ import

    App from “components/App” ALBO { main: “App.js” }
  24. 88.

    LEPIEJ const AuthenticatedApp = React.lazy(() => import(“./AuthenticatedApp”) ); { userLoggedIn()

    ? <React.Suspense fallback={"... Loading”}> <AuthenticatedApp /> </React.Suspense> : <UnauthenticatedApp /> }
  25. 91.

    import TodosAPI from “api/todos”; function TodoList() { useEffect(() => {

    TodosAPI.getAllTodos().then( /* … */ ); }, []) } FASADA DLA API
  26. 92.

    TodosAPI = { getAllTodos: () => { fetch("example.com/todos", { method:

    “get” }).then( /* … */ ); } }; FASADA DLA API
  27. 93.

    import TodosAPI from “api/TodosAPI”; import apiClient from “api/FetchClient”; function TodoList()

    { useEffect(() => { new TodosAPI(apiClient) .getAllTodos() .then( /* … */ ); }, []) } ADAPTER DLA API
  28. 94.

    import TodosAPI from “api/TodosAPI”; import apiClient from “api/FakeClient”; function TodoList()

    { useEffect(() => { new TodosAPI(apiClient) .getAllTodos() .then( /* … */ ); }, []) } ADAPTER DLA API
  29. 95.

    ADAPTER DLA API class TodosAPI constructor(client) { this.client = client;

    } getAllTodos: () => { this.client.getAll("example.com/todos"); } };
  30. 96.

    Client = { getAll: function (url) {…}, getOne: function (url,

    id) {…}, post: function (url, payload) {…}, put: function (url, id, payload) {…}, patch: function (url, id, payload) {…}, delete: function (url, id) {…}, } ADAPTER DLA API
  31. 97.
  32. 99.
  33. 100.

    WARTO MIEĆ WSZYSTKIE TYPY AKCJI W JEDNYM PLIKU TODO_ADD addTodo(todo)

    TODO_EDIT editTodo(todo) TODO_REPLACE replaceTodo(todo) TODO_DELETE deleteTodo(todo)
  34. 101.

    KOLOKACJA SELECTORÓW I REDUCERÓW todosReducer = (state = [], action)

    { switch(action.type) { case TODO_ADD: return […state, action.todo]; } } getAllTodos(state) => state; getTodoById(state, id) => state.find(todo => todo.id === id)
  35. 102.

    TESTOWANIE BLACK BOX it(“Adds a todo”, () => { const

    todoToAdd = {id: 42, title: “abc”}; store.dispatch(addTodo(todoToAdd)); expect( getTodoById(store.getState(), 42) ).toEq(todoToAdd); }
  36. 107.
  37. 108.