• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

React - BlockPicker, zmiana koloru notatki

Object Storage Arubacloud
0 głosów
236 wizyt
pytanie zadane 24 października 2020 w JavaScript przez Nerez Użytkownik (970 p.)

Cześć, ostatnio zacząłęm swoją przygodę z reactem. Moim pierwszym projektem jest aplikacja typu "todo". Użytkownik wprowadza co ma zrobić, naciska "dodaj" i notatka zostaje wyświetlona niżej. Chciałbym tym notatką nadać jakiś ciekawy kolor, no i z pomocą przyszedł mi "BlockPicker". Poniżej przedstawiam wam 2 pliki, z którymi nie mogę się uporać.


Form.js:

import React, { useState } from 'react';
import { BlockPicker } from 'react-color';
import Tippy from 'tippy.js'

const Form = ({ setInputText,todos, setTodos, inputText, setStatus}) => {
  const [selectedColor, setSelectedColor] = useState('#ffffff')
  function inputTextHandler(e) {
    setInputText(e.target.value);
  }

  const submitTodoHandler = (e) => {
    e.preventDefault();
    setTodos([
    ...todos,{text: inputText, completed: false, id: Math.random() * 1000}
    ]);
    setInputText('');
  };

  const statusHandler = (e) => {
    setStatus(e.target.value )
  }

  const colorHandler = (e) => {
    e.preventDefault();
  }
  return(
    <form>
    <BlockPicker 
      color={selectedColor}
      onChangeComplete={color => setSelectedColor(color.hex)}
    />
    <button onClick={colorHandler} className='color-picker'>
      C
    </button>
      <input  
        value={inputText}
        onChange = {inputTextHandler} 
        type="text" 
        className="todo-input" />
      <button onClick = {submitTodoHandler} className="todo-button" type="submit">
      <i className="fas fa-plus-circle"></i>
      </button>
      <div className="select">
        <select onChange={statusHandler} name="todos" className="filter-todo">
          <option value="all">All</option>
          <option value="completed">Completed</option>
          <option value="uncompleted">Uncompleted</option>
        </select>
      </div>
    </form>
    )
}

export default Form;

 

Todo.js:

import React from 'react';
import Form from './Form'

const Todo = ({ text,todo,todos,setTodos, selectedColor }) => {

    const deleteHandler = () => {
        setTodos(todos.filter(el => el.id !== todo.id))
    }

    const completeHandler = () => {
        setTodos(todos.map((item) => {
           if(item.id ===  todo.id){
               return{
                   ...item, completed: !item.completed
               };
            }
           return item;
        })
        );
    };
    return(
        <div className='todo' style={{backgroundColor: selectedColor}}>
            <li className={`todo-item ${todo.completed ? "completed" : ''}`}>{text}</li>
            <button onClick={completeHandler} className='complete-btn'>
                <i className='fas fa-check'></i>
            </button>
            <button onClick={deleteHandler} className='trash-btn'> 
                <i className='fas fa-trash'></i>
            </button>
        </div>
    );
}

export default Todo;

Jak możecie zauważyć w pliku Form.js mam "selectedColor". Chciałbym móc jakoś tego użyć do ustawienia koloru aktualnie dodawanej notatki. Po użyciu console.log(selectedColor) w Form.js dostaje odpowiedź z kodem hex wybranego koloru, a w pliku Todo.js zawsze wyświetla się "undefined". Byłby ktoś w stanie pomóc zrobić to w ten sposób, aby po wybraniu danego koloru, kolor notatki zmieniał się właśnie na ten na stałe?

komentarz 24 października 2020 przez ScriptyChris Mędrzec (190,190 p.)

W którym konkretnie miejscu selectedColor ma wartość undefined? Z tego co widzę, importujesz komponent Form (i to w nim jest zmienna selectedColor) w module Todo, ale nie używasz go - czy to tak powinno być?

komentarz 24 października 2020 przez Nerez Użytkownik (970 p.)
Tak jak pisałem dopiero zaczynam więc zdarzają się banalne błędy. Jak widzisz w Todo.js mam coś takiego jak style={{backgroundColor: selectedColor}} i właśnie w tym miejscu chciałbym użyć tej zmiennej z form.js. Undefined wychodzi w pliku todo.js.
komentarz 24 października 2020 przez ScriptyChris Mędrzec (190,190 p.)

To pokaż proszę gdzie i jak używasz komponentu Todo, bo w powyższym kodzie tego nie widzę.

komentarz 24 października 2020 przez Nerez Użytkownik (970 p.)

Pozostale czesci kodu:

App.js

import React, { useState, useEffect } from 'react';
import './App.css';
import Form from './components/Form'
import TodoList from './components/TodoList'

function App({}) {

  //States
  const [inputText, setInputText] = useState("");
  const [todos, setTodos] = useState([]);
  const [status, setStatus] = useState('all');
  const [filteredTodos, setFilteredTodos] = useState([]);
  const [selectedColor, setSelectedColor] = useState('#ffffff')
    //RUN ONCE WHEN APP STARTS
    useEffect(() => {
      getLocalTodos();
    }, [])
    //USE EFFECT
    useEffect(() => {
      filterHandler();
      saveLocalTodos();
  }, [todos, status])

  //Functions
  const filterHandler = () => {
    switch(status) {
      case "completed":
        setFilteredTodos(todos.filter(todo => todo.completed === true));
        break;
      case "uncompleted":
        setFilteredTodos(todos.filter(todo => todo.completed === false));
        break;
      default:
        setFilteredTodos(todos);
        break;
    }
  };

  //Save to localStorage
  const saveLocalTodos = () => {
    localStorage.setItem('todos', JSON.stringify(todos));
    }
  const getLocalTodos = () => {
    if(localStorage.getItem('todos') === null){
      localStorage.setItem('todos', JSON.stringify([]));
    }else{
      let todoLocal = JSON.parse(localStorage.getItem('todos'))
      setTodos(todoLocal);
    }

  }
  return (
    <div className="App">
      <header>
        <h1>Todo</h1>
      </header>
      <Form  
        inputText = {inputText}
        todos = {todos}
        setTodos ={setTodos}
        setInputText={setInputText}
        setStatus={setStatus}
        selectedColor={selectedColor}
        setSelectedColor={setSelectedColor}
        />
      <TodoList  
      setTodos={setTodos} 
      todos={todos} 
      filteredTodos={filteredTodos} 
        selectedColor={selectedColor}
        setSelectedColor={setSelectedColor}
      />
    </div>
  );
}
export default App;

 

TodoList.js

import React from 'react'
//Import Components
import Todo from './Todo'
import Form from './Form'

const TodoList = ({ todos,setTodos, filteredTodos, selectedColor, setSelectedColor }) => {
    return(
       <div className="todo-container">
        <ul className="todo-list">
          {filteredTodos.map(todo => (
            <Todo 
            key={todo.id} 
            text={todo.text} 
            setTodos={setTodos} 
            todo={todo}
            todos={todos}
            selectedColor={selectedColor}
            setSelectedColor={setSelectedColor}
            />
          ))}
        </ul>
      </div>
    )
}

export default TodoList;

 

komentarz 24 października 2020 przez ScriptyChris Mędrzec (190,190 p.)
edycja 24 października 2020 przez ScriptyChris

Czy selectedColor ma jakąś wartość (nie jest undefined) w returnie (linijki od 53-73) komponentu App oraz w komponencie TodoList?


Na marginesie: do komponentu Form też przekazujesz zmienną selectedColor, mimo że wewnątrz nie bierzesz jej z argumentu, tylko tworzysz (znowu) tę zmienną lokalnie poprzez hooka useState. Skoro przekazujesz do komponentu Form tę zmienną, to nie twórz jej wewnątrz tego komponentu.

komentarz 24 października 2020 przez Nerez Użytkownik (970 p.)
Moglbys dokladniej doradzic co mam zrobic?
komentarz 24 października 2020 przez ScriptyChris Mędrzec (190,190 p.)

Wstaw console.log('selectedColor', selectedColor) w miejsca, o których wspomniałem i pokaż co rzuca konsola przeglądarki.

komentarz 25 października 2020 przez Nerez Użytkownik (970 p.)
Udało się to naprawić, ale myślałem, że jest jakaś opcja żeby szło to prosto form-todo, narazie idzie form-app-todolist-todo.
komentarz 25 października 2020 przez ScriptyChris Mędrzec (190,190 p.)

Żeby propsy przekazać bezpośrednio, można skorzystać z Context API lub patternu kompozycji.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 226 wizyt
pytanie zadane 6 lipca 2022 w JavaScript przez zerakot Obywatel (1,870 p.)
0 głosów
0 odpowiedzi 194 wizyt
0 głosów
0 odpowiedzi 100 wizyt

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...