简体   繁体   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

I am trying to deploy the react app on netlify.我正在尝试在 netlify 上部署 react 应用程序。 Locally, my react todo app is working fine and local storage is persisting the data as well (locally).在本地,我的 react todo 应用程序运行良好,并且本地存储也在(本地)保存数据。 but when I deployed the web app on netlify, after visiting the live link it's showing me this error: "Unexpected token u in JSON at position 0 at JSON.parse" as it is retrieving the undefined.但是当我在 netlify 上部署 Web 应用程序时,在访问实时链接后,它向我显示了这个错误:“JSON.parse 中位置 0 处的 JSON 中的意外令牌 u”,因为它正在检索未定义的内容。 Solutions I tried: checked the typo 2: checked the object in the console which is displaying the data correctly.我尝试过的解决方案:检查错字 2:检查控制台中正确显示数据的对象。 3: i also kept the getTodoFromLocal function inside App() function and kept initial state of const [todos, setTodos] = useState([]); 3:我还在 App() 函数中保留了 getTodoFromLocal 函数,并保留了 const [todos, setTodos] = useState([]); 的初始状态。 (to empty array) but this is not persisting data on page reloads (到空数组)但这不是在页面重新加载时保留数据

my code App.js我的代码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 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;

Form.js表单.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 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;

Live link: https://clinquant-parfait-ceab31.netlify.app/直播链接: https ://clinquant-parfait-ceab31.netlify.app/

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

I figured the error.我想出了错误。 Going step by step.一步一步走。

  1. You have getTodoFromLocal which is called when you setTodos const [todos, setTodos] = useState(getTodoFromLocal());你有getTodoFromLocal ,当你 setTodos const [todos, setTodos] = useState(getTodoFromLocal()); here.这里。

  2. As localStorage.getItem("todos") is null, you set todos to [] but do not return anything which returns undefined and value of todos is changed to undefined .由于localStorage.getItem("todos")为空,您将todos设置为[]但不返回任何返回 undefined 的内容,并且 todos 的值更改undefined

  3. Then you have the function saveToLocal in which you store todos in localStorage .which is called in useEffect whenever todos change.然后你就有了saveToLocal函数,你可以在其中将todos存储在localStorage中。每当 todos 发生变化时,就会在 useEffect 中调用它。

  4. Todos changed to undefined > useEffect is called > in saveToLocal function todos(undefined) is stored in localStorage. Todos 更改为undefined > useEffect 被调用 > 在saveToLocal函数中 todos(undefined) 存储在 localStorage 中。

updated code:更新代码:

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