Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 将Redux状态持久化到本地存储_Arrays_Reactjs_Redux_Local Storage - Fatal编程技术网

Arrays 将Redux状态持久化到本地存储

Arrays 将Redux状态持久化到本地存储,arrays,reactjs,redux,local-storage,Arrays,Reactjs,Redux,Local Storage,我用React创建了一个简单的应用程序。我已尝试使用本地存储持久化状态。但是,我添加的本地存储代码以某种方式阻止我的组件完全呈现。不仅TODO保存在不显示的状态,而且我的任何组件都不会渲染。我得到一个关于刷新的空白页。有人能帮我找出问题所在吗 下面是在包含本地存储代码后,在初始保存时发生的情况。它可以很好地加载组件,但不会显示已处于状态的待办事项: 在使用表单添加到dos并刷新页面后,会发生这种情况。没有显示任何组件。只是一张空白页 这是我的index.js文件中的本地存储代码。我很确定问题

我用React创建了一个简单的应用程序。我已尝试使用本地存储持久化状态。但是,我添加的本地存储代码以某种方式阻止我的组件完全呈现。不仅TODO保存在不显示的状态,而且我的任何组件都不会渲染。我得到一个关于刷新的空白页。有人能帮我找出问题所在吗

下面是在包含本地存储代码后,在初始保存时发生的情况。它可以很好地加载组件,但不会显示已处于状态的待办事项:

在使用表单添加到dos并刷新页面后,会发生这种情况。没有显示任何组件。只是一张空白页

这是我的
index.js
文件中的本地存储代码。我很确定问题出在这里,但我也包括了其他组件和减速器的代码:

const persistedState = localStorage.getItem('state') ? JSON.parse(localStorage.getItem('state')) : [];

const store = createStore(reducer, persistedState);

store.subscribe(() => {
    localStorage.setItem('state', JSON.stringify(store.getState()));
})
整个
index.js
文件:

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from "redux";
import { Provider } from "react-redux";
import './index.css';
import App from './App';
import { reducer } from "./reducers/todoReducer";
import * as serviceWorker from './serviceWorker';

const persistedState = localStorage.getItem('state') ? JSON.parse(localStorage.getItem('state')) : [];

const store = createStore(reducer, persistedState);

store.subscribe(() => {
    localStorage.setItem('state', JSON.stringify(store.getState()));
})

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, 
    document.getElementById('root')
    );
TodoForm.js

import Todo from "./Todo";

const TodoList = props => {

    return (
        <ul className="task-list">
            {props.state.map(task => (
                <Todo task={task} />
            ))}
        </ul>
    )
}

const mapStateToProps = state => {
    return {
        state: state
    }
}

export default connect(mapStateToProps)(TodoList);
const TodoForm = props => {
    const [newItemText, setNewItemText] = useState("");

    const handleChanges = e => {
        e.preventDefault();
        setNewItemText(e.target.value);
      };

    const saveState = () => localStorage.setItem("props.state", JSON.stringify(props.state));

    useEffect(() => {
        const todos = localStorage.getItem('state');
        if (todos) props.setState({ [props.state]: JSON.parse(props.state) })
    }, [])

    return (
        <div className="form-div">
                <input
                    className="add-input"
                    name="todo"
                    type="text"
                    placeholder="enter a task"
                    value={newItemText}
                    onChange={handleChanges}
                />
                <button 
                    className="add-button"
                    onClick = {e => {
                    e.preventDefault();
                    props.addItem(newItemText);
                    saveState();
                    }}>Add a Task
                </button>
                <button 
                    className="add-button"
                    onClick={e => {
                    e.preventDefault();
                    props.removeCompleted();
                    }}>Remove Completed
                </button>
        </div>

    )
}

const mapStateToProps = state => {
    return {
        state: state
    } 
}

export default connect(mapStateToProps, {addItem, removeCompleted})(TodoForm);
const Todo = props => {

    return (
            <li 
                className="tasks"
                style={{textDecoration: props.task.completed ? 'line-through' : 'none'}} 
                onClick={() => props.toggleCompleted(props.task.id)}>
                    {props.task.item}
            </li>
    )
}

const mapStateToProps = state => {
    return {
        state: state
    }
}

export default connect(mapStateToProps, {toggleCompleted})(Todo);
export const initialState = [
    { item: 'Learn about reducers', completed: false, id: 1 },
    { item: 'review material from last week', completed: false, id: 2 },
    { item: 'complete reducer todo project', completed: false, id: 3 }
]

export const reducer = (state = initialState, action) => {
    switch(action.type) {
        case ADD_ITEM:
            // console.log(action.payload)
            return [
                ...state,
                {
                    item: action.payload,
                    completed: false,
                    id: Date.now()
                }
            ]
        case TOGGLE_COMPLETED:
            const toggledState = [...state];
            toggledState.map(item => {
                if(item.id === action.payload) {
                    item.completed = !item.completed;
                }
            })
            console.log(toggledState);
            state = toggledState;
            return state;

        case REMOVE_COMPLETED:
           return state.filter(item => !item.completed);
        default:
            return state;
    }
}

export default reducer;
import React from 'react';
import './App.css';

// components
import TodoList from "./components/TodoList";
import TodoForm from "./components/TodoForm";

function App() {

  return (
    <div className="App">
        <h1 className="title">To Do List</h1>
        <TodoList />
        <TodoForm />
    </div>
  );
}

export default App;
todoReducer.js

import Todo from "./Todo";

const TodoList = props => {

    return (
        <ul className="task-list">
            {props.state.map(task => (
                <Todo task={task} />
            ))}
        </ul>
    )
}

const mapStateToProps = state => {
    return {
        state: state
    }
}

export default connect(mapStateToProps)(TodoList);
const TodoForm = props => {
    const [newItemText, setNewItemText] = useState("");

    const handleChanges = e => {
        e.preventDefault();
        setNewItemText(e.target.value);
      };

    const saveState = () => localStorage.setItem("props.state", JSON.stringify(props.state));

    useEffect(() => {
        const todos = localStorage.getItem('state');
        if (todos) props.setState({ [props.state]: JSON.parse(props.state) })
    }, [])

    return (
        <div className="form-div">
                <input
                    className="add-input"
                    name="todo"
                    type="text"
                    placeholder="enter a task"
                    value={newItemText}
                    onChange={handleChanges}
                />
                <button 
                    className="add-button"
                    onClick = {e => {
                    e.preventDefault();
                    props.addItem(newItemText);
                    saveState();
                    }}>Add a Task
                </button>
                <button 
                    className="add-button"
                    onClick={e => {
                    e.preventDefault();
                    props.removeCompleted();
                    }}>Remove Completed
                </button>
        </div>

    )
}

const mapStateToProps = state => {
    return {
        state: state
    } 
}

export default connect(mapStateToProps, {addItem, removeCompleted})(TodoForm);
const Todo = props => {

    return (
            <li 
                className="tasks"
                style={{textDecoration: props.task.completed ? 'line-through' : 'none'}} 
                onClick={() => props.toggleCompleted(props.task.id)}>
                    {props.task.item}
            </li>
    )
}

const mapStateToProps = state => {
    return {
        state: state
    }
}

export default connect(mapStateToProps, {toggleCompleted})(Todo);
export const initialState = [
    { item: 'Learn about reducers', completed: false, id: 1 },
    { item: 'review material from last week', completed: false, id: 2 },
    { item: 'complete reducer todo project', completed: false, id: 3 }
]

export const reducer = (state = initialState, action) => {
    switch(action.type) {
        case ADD_ITEM:
            // console.log(action.payload)
            return [
                ...state,
                {
                    item: action.payload,
                    completed: false,
                    id: Date.now()
                }
            ]
        case TOGGLE_COMPLETED:
            const toggledState = [...state];
            toggledState.map(item => {
                if(item.id === action.payload) {
                    item.completed = !item.completed;
                }
            })
            console.log(toggledState);
            state = toggledState;
            return state;

        case REMOVE_COMPLETED:
           return state.filter(item => !item.completed);
        default:
            return state;
    }
}

export default reducer;
import React from 'react';
import './App.css';

// components
import TodoList from "./components/TodoList";
import TodoForm from "./components/TodoForm";

function App() {

  return (
    <div className="App">
        <h1 className="title">To Do List</h1>
        <TodoList />
        <TodoForm />
    </div>
  );
}

export default App;
App.js

import Todo from "./Todo";

const TodoList = props => {

    return (
        <ul className="task-list">
            {props.state.map(task => (
                <Todo task={task} />
            ))}
        </ul>
    )
}

const mapStateToProps = state => {
    return {
        state: state
    }
}

export default connect(mapStateToProps)(TodoList);
const TodoForm = props => {
    const [newItemText, setNewItemText] = useState("");

    const handleChanges = e => {
        e.preventDefault();
        setNewItemText(e.target.value);
      };

    const saveState = () => localStorage.setItem("props.state", JSON.stringify(props.state));

    useEffect(() => {
        const todos = localStorage.getItem('state');
        if (todos) props.setState({ [props.state]: JSON.parse(props.state) })
    }, [])

    return (
        <div className="form-div">
                <input
                    className="add-input"
                    name="todo"
                    type="text"
                    placeholder="enter a task"
                    value={newItemText}
                    onChange={handleChanges}
                />
                <button 
                    className="add-button"
                    onClick = {e => {
                    e.preventDefault();
                    props.addItem(newItemText);
                    saveState();
                    }}>Add a Task
                </button>
                <button 
                    className="add-button"
                    onClick={e => {
                    e.preventDefault();
                    props.removeCompleted();
                    }}>Remove Completed
                </button>
        </div>

    )
}

const mapStateToProps = state => {
    return {
        state: state
    } 
}

export default connect(mapStateToProps, {addItem, removeCompleted})(TodoForm);
const Todo = props => {

    return (
            <li 
                className="tasks"
                style={{textDecoration: props.task.completed ? 'line-through' : 'none'}} 
                onClick={() => props.toggleCompleted(props.task.id)}>
                    {props.task.item}
            </li>
    )
}

const mapStateToProps = state => {
    return {
        state: state
    }
}

export default connect(mapStateToProps, {toggleCompleted})(Todo);
export const initialState = [
    { item: 'Learn about reducers', completed: false, id: 1 },
    { item: 'review material from last week', completed: false, id: 2 },
    { item: 'complete reducer todo project', completed: false, id: 3 }
]

export const reducer = (state = initialState, action) => {
    switch(action.type) {
        case ADD_ITEM:
            // console.log(action.payload)
            return [
                ...state,
                {
                    item: action.payload,
                    completed: false,
                    id: Date.now()
                }
            ]
        case TOGGLE_COMPLETED:
            const toggledState = [...state];
            toggledState.map(item => {
                if(item.id === action.payload) {
                    item.completed = !item.completed;
                }
            })
            console.log(toggledState);
            state = toggledState;
            return state;

        case REMOVE_COMPLETED:
           return state.filter(item => !item.completed);
        default:
            return state;
    }
}

export default reducer;
import React from 'react';
import './App.css';

// components
import TodoList from "./components/TodoList";
import TodoForm from "./components/TodoForm";

function App() {

  return (
    <div className="App">
        <h1 className="title">To Do List</h1>
        <TodoList />
        <TodoForm />
    </div>
  );
}

export default App;

localStore
部分看起来不错,我想问题出在其他地方。如果出现任何错误消息或警告,您是否检查了
控制台
?您能否添加您如何调用这些操作以及另外的
App.js
?谢谢嗯,我没有看到任何错误消息。我编辑了这篇文章,添加了你要求的代码。我还添加了两个屏幕截图来显示发生了什么:在初始加载时,我的所有组件都呈现良好,但应用程序没有拾取状态中存储的数据。刷新后,所有组件都会消失。没有显示任何内容。这可能是中间件问题吗?如果打开控制台并在那里键入
localStorage.getItem('state')
,您会在那里看到什么?可能是缓存问题。可能是一个旧值被卡住了。它记录了我通过表单添加的任务:“[{”item:“go to the store”,“completed”:false,“id”:157796268922}”