v2.5.2
Giriş yap

React'e başlarken izlediğim yol doğru mu, Ne yapmalıyım?

delarmuss
161 defa görüntülendi

Merhabalar ben React'e başlıyorum ve az çok herkesin yaptığı gibi todo uygulaması ile başlamak istedim ve aşağıdaki gibi bir yapı oluşturarak ilerledim. Sormak istediğim şey ise gittiğim yol doğru mu? yoksa yanlış mı?, yanlışlarım neler?, ayrıca uzun zamandır kod yazmakla uğraşmadığım için todo silme kısmında tıkandım normalde videolarda izleyince anlıyorum fakat yaparken zorlanıyorum bu yönde kendimi nasıl geliştirebilirim?

  • not: ilk defa konu açıyorum yanlışlarım varsa kusura bakmayın

App.jsx

import TodoForm from "./components/TodoForm.jsx";
import {useState} from "react";

export default function App() {
  const [todos, setTodos] = useState([]);

  return (
    <>
      <TodoForm todos={todos} setTodos={setTodos}/>
    </>
  )
}

TodoForm.jsx

import TodoHeader from "./TodoHeader.jsx";
import Todos from "./Todos.jsx";

export default function TodoForm({todos, setTodos}) {
  return (
    <form>
      <TodoHeader setTodos={setTodos}/>
      <Todos todos={todos} setTodos={setTodos}/>
    </form>
  )
}

TodoHeader.jsx

import {useState} from "react";

export default function TodoHeader({todos, setTodos}) {
  const [entry, setEntry] = useState("");

  const addTodo = (e) => {
    e.preventDefault();
    setTodos(prev => ([...prev, entry]))
    setEntry("")
  }

  return (
    <>
      <h1>Todos</h1>
      <input type={"text"} placeholder={"entry..."} value={entry} onChange={(e => setEntry(e.target.value))}/>
      <button type={"submit"} onClick={addTodo}>Add</button>
    </>
  )
}

Todos.jsx

import Todo from "./Todo.jsx";

export default function Todos({todos, setTodos}) {
  return (
    <>
      <Todo todos={todos} setTodos={setTodos}/>
    </>
  )
}

Todo.jsx

export default function Todo({todos, setTodos}) {
  const deleteTodo = e => {
    e.preventDefault()
  }

  return (
    <>
      {
        todos.map(todo => (
          <div key={todo}>
            {todo}
            <button onClick={deleteTodo}>Delete</button>
          </div>
        ))
      }
    </>
  )
}
tayfunerbilen
293 gün önce

oncelikle iyi ogrenmeler, uzun bir surec, keyifli bir surec, bazen sancili bir surec olsada, basta kodu yazip calistigindan emin olursun, sonra kodunu refactor eder daha iyi nasil yazarim diye dusunursun, sonra daha performansli nasil yazarim diye dusunursun, kod tekrari nasil yapmam diye dusunursun vs. vs. bunlar zamanla oturur.

senin koduna ufak bir yorumum olacak, isimlendirmede TodoForm demissin en ust component'ine ama form ile ilgili bir sey olmadigi icin belki Todos olsa component'in adi daha iyi olur.

ayrica muhtemelen yeni basladigin icin state'i useState ile tutuyorsun ve parent'dan child component'lere kullanmak icin prop geciyorsun, bunun yerine react'in kendi icinde bulunan context yapisini deneyebilirsin.

TodoHeader component'i yerine AddTodo diye isimlendirip icinde form kullanarak islemlerini onSubmit'de handle edebilirsin.

Todos ve Todo componentlerin teorida ayni isi yapiyor, mantik olarak Todos icinde map'leyip Todo icinde todo'yu gostermen daha dogru olurdu.


Simdi tum bu yazdiklarima gore kodunu yeniden yazacak olsam soyle yazardim:

context/todo.js

import { createContext, useContext, useState } from "react";

export const TodoContext = createContext();
export const useTodos = () => useContext(TodoContext);

export const TodoProvider = ({ children }) => {
  const [todos, setTodos] = useState([]);

  const addTodo = (data) => {
    setTodos((todos) => [...todos, data]);
  };

  const removeTodo = (key) => {
    setTodos((todos) => todos.filter((todo, i) => i !== key));
  };

  const removeAllTodos = () => {
    setTodos([]);
  };

  // child componentlerin ulasacagi datalar
  const contextData = {
    todos,
    addTodo,
    removeTodo,
    removeAllTodos
  };

  return (
    <TodoContext.Provider value={contextData}>{children}</TodoContext.Provider>
  );
};

burada react'in context yapisi ile state'lerimizi child componentlerde kullanabilmek icin global olarak yonetiyoruz. Ayrica todo ekleme, silme, tumunu silme gibi metodlarida burada yazip context'in icine atiyorum, boylece useTodos() cagirdigimiz her yerde contextData icindekilere erisebiliyoruz.

components/add-todo.jsx

import { useState } from "react";
import { useTodos } from "../context/todo";

export default function AddTodo() {
  const { addTodo } = useTodos();
  const [todo, setTodo] = useState("");

  const handleChange = (e) => {
    e.preventDefault();
    addTodo({
      title: todo
    });
    setTodo("");
  };

  return (
    <form onSubmit={handleChange}>
      <input value={todo} onChange={(e) => setTodo(e.target.value)} />
      <button disabled={!todo} type="submit">
        Ekle
      </button>
    </form>
  );
}

gordugun gibi, todo ekleme component'inde eklenecek todo'yu context icindeki addTodo metodunu cagirip kullaniyoruz.

components/todos.jsx

import { useTodos } from "../context/todo";
import Todo from "./todo";

export default function Todos() {
  const { todos, removeAllTodos } = useTodos();

  const deleteHandle = () => {
    removeAllTodos();
  };

  if (todos.length === 0) {
    return <div>hic todo eklenmemis :(</div>;
  }

  return (
    <>
      {todos.map((todo, key) => (
        <Todo data={todo} id={key} key={key} />
      ))}
      <button onClick={deleteHandle}>Tumunu sil</button>
    </>
  );
}

burada da ayni mantikta todos dizisini ve removeAllTodos metodunu context'en aliyoruz.

components/todo.jsx

import { useTodos } from "../context/todo";

export default function Todo({ data, id }) {
  const { removeTodo } = useTodos();
  const deleteHandle = () => {
    removeTodo(id);
  };

  return (
    <div>
      {data.title}
      <button onClick={deleteHandle}>Sil</button>
    </div>
  );
}

silme isleminde ise dizideki index numarasina gore yaptim, bu elbette rastgele bir id uretilip todo icinde tutulsaydi ona gorede eslestirme yapip kullanabilirsin, basit bir todo uygulamasi oldugu icin bunu yapmadim simdilik.

app.jsx

import { TodoProvider } from "./context/todo";
import AddTodo from "./components/add-todo";
import Todos from "./components/todos";
export default function App() {
  return (
    <TodoProvider>
      <AddTodo />
      <Todos />
    </TodoProvider>
  );
}

Son olarak TodoProvider i context dosyamizdan alip diger component'leri bunun icine yaziyoruz, bu sayede diger componentlerde context icindeki degerlere erisip islem yapabiliyoruz.

calisan ornegine suradan bakabilirsin:
https://codesandbox.io/s/sleepy-volhard-rz7645

anlamadigin ya da merak ettigin bir sey olursa sormaktan cekinme :)