簡體   English   中英

在 netlify 上部署后,React.js todo 應用程序中位置 0 處 JSON 中的意外令牌 u

[英]Unexpected token u in JSON at position 0 in React.js todo app after deployment on netlify

我正在嘗試在 netlify 上部署 react 應用程序。 在本地,我的 react todo 應用程序運行良好,並且本地存儲也在(本地)保存數據。 但是當我在 netlify 上部署 Web 應用程序時,在訪問實時鏈接后,它向我顯示了這個錯誤:“JSON.parse 中位置 0 處的 JSON 中的意外令牌 u”,因為它正在檢索未定義的內容。 我嘗試過的解決方案:檢查錯字 2:檢查控制台中正確顯示數據的對象。 3:我還在 App() 函數中保留了 getTodoFromLocal 函數,並保留了 const [todos, setTodos] = useState([]); 的初始狀態。 (到空數組)但這不是在頁面重新加載時保留數據

我的代碼App.js

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


// get data from local
const getTodoFromLocal = () => {
  if(localStorage.getItem("todos") === null){
    localStorage.setItem("todos", JSON.stringify([]));
  } else {
      try{
        let localTodo = localStorage.getItem("todos");
        let parsedTodo = JSON.parse(localTodo)
        return parsedTodo; 
      } catch(error) {
        console.log(error);
      }
   }
 }

const App = () => {
  // states
  const [inputText, setInputText] = useState("");
  const [todos, setTodos] = useState(getTodoFromLocal());
  const [status, setStatus] = useState("all");
  const [filteredTodo, setFilteredTodo] = useState([]);

  // run this only once when app loads
  useEffect(() => {
    getTodoFromLocal();
  }, [])

  // Run once when app loads and every time when there is any change in todos ot status
  useEffect(() => {
    filterHandler();
    saveToLocal();
  }, [todos, status])

  // functions
  const filterHandler = () =>{
    switch (status) {
      case 'completed':
       setFilteredTodo(todos.filter(todo => todo.completed === true));
       break;
      case 'incompleted':
        setFilteredTodo(todos.filter(todo => todo.completed === false));
        break;
      default:
        setFilteredTodo(todos);
        break;
    }
  }

  // save to local storage / set todos;
  const saveToLocal = () => {
    localStorage.setItem("todos", JSON.stringify(todos));
  };
  

  return (
    <div className="App">
      <Header />
      <Form inputText = {inputText} 
        setInputText={setInputText} 
        todos={todos}  
        setTodos={setTodos} 
        setStatus={setStatus}
        />
      <TodoList 
        todos={todos} 
        setTodos={setTodos} 
        filteredTodo={filteredTodo}
      />
    </div>
  );
}

export default App;

TodoList.js

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

const TodoList = ({todos, setTodos, filteredTodo}) =>  {
  return (
    <div className='todo-container'>
        <ul className='todo-list'>
          {filteredTodo && filteredTodo.map(todo => (
            <TodoItem 
              key={todo.id} 
              todo={todo} 
              todos={todos} 
              setTodos={setTodos}
              text={todo.text}
              />
          ))}
        </ul>
    </div>
  )
}

export default TodoList;

表單.js

import React from 'react';
import './form.css';
import { v4 as uuidv4 } from 'uuid';


function Form({inputText, setInputText, todos, setTodos, setStatus}) {

  const inputHandler = (e) => {
    setInputText(e.target.value);
  }

  const submitHandler = (e) =>{
    e.preventDefault();
    // generate unique id for todo lists.
    const uniqueId = uuidv4(); 
    //add todo object on click of button
    const addItem = !inputText ? alert("enter somthing")  :  setTodos([
      ...todos, {id: uniqueId, text: inputText, completed: false }
    ]);
 
    //reset the input field after adding todo
    setInputText("");

    return addItem;
  }

  // filtered todo
  const statusTodo = (e) => {
    setStatus(e.target.value);
  }

  return (
    <form>
        <input  type="text" className="todo-input" onChange={inputHandler} value={inputText}/>
        <button className="todo-button" type="submit" onClick={submitHandler}>
            <i className="fas fa-plus-square"></i>
        </button>
        <div className="select">
          <select onChange={statusTodo} name="todos" className="filter-todo">
              <option value="all">All</option>
              <option value="completed">Completed</option>
              <option value="incompleted">Incompleted</option>
          </select>
          <span><i className="fas fa-chevron-down"></i></span>
        </div>
  </form>
  )
}

export default Form;

TodoItem.js

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

const TodoItem = ({text, todo, todos, setTodos}) => {
  //delete an item;
  const deleteHandler = () => {
    setTodos(todos.filter(el => el.id !== todo.id))
  }

  const completeHandler = () => {
    setTodos(todos.map((item )=> {
      if(item.id === todo.id){
        return {
          ...item, completed: !todo.completed
        }
      }
      return item;
    }));
  }

  return (
    <div className='todo'>
        <li className={`todo-item ${todo.completed ? 'completed' : "" }`}>{text}</li>
        <button className='complete-btn' onClick={completeHandler}>
            <i className='fas fa-check'></i>
        </button> 
        <button className='trash-btn' onClick={deleteHandler}>
            <i className='fas fa-trash'></i>
        </button> 
    </div>
  )
}

export default TodoItem;

直播鏈接: https ://clinquant-parfait-ceab31.netlify.app/

Github 鏈接: https ://github.com/Mehreen57/Todo-app-react

我想出了錯誤。 一步一步走。

  1. 你有getTodoFromLocal ,當你 setTodos const [todos, setTodos] = useState(getTodoFromLocal()); 這里。

  2. 由於localStorage.getItem("todos")為空,您將todos設置為[]但不返回任何返回 undefined 的內容,並且 todos 的值更改undefined

  3. 然后你就有了saveToLocal函數,你可以在其中將todos存儲在localStorage中。每當 todos 發生變化時,就會在 useEffect 中調用它。

  4. Todos 更改為undefined > useEffect 被調用 > 在saveToLocal函數中 todos(undefined) 存儲在 localStorage 中。

更新代碼:

if (localStorage.getItem("todos") === null) {
    localStorage.setItem("todos", JSON.stringify([]));
    return []
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM