Home > Net >  How save style in the local storage
How save style in the local storage

Time:08-17

I have such a project. Here I want the button border save in the local storage.The buttons are divided into categories. For example when you refresh the page after selecting a sports button, the border of the button disappears. I want save btn border in the localstorage. I saved the categories in memory, but I can't make the border of the selected button.How can I fix it?

import React, { useEffect, useState } from "react";
import SpinnerLoad from './components/SpinnerLoad'
import NewsItem from "./components/NewsItem";
import Category from "./components/data/Category"
const App = () => {

  const [state, setState] = useState([]);
  const [loading, setLoading] = useState(false)
  const [selected, setSelected] = useState('');

  const fetchValue = (category, index) => {
    localStorage.setItem("category", category);
    localStorage.setItem("selected", index);
    fetch(`https://inshorts-api.herokuapp.com/news?category=${category}`)
      .then(res => res.json())
      .then(res => {
        setState(res.data)
        setLoading(true)
      })
      .catch((error) => console.log(error))
    setLoading(false);
  };

  const CategoryButton = ({ category, i  }) => (
    // passing index --> i to the fetch Value
    <button onClick={() =>{ fetchValue(category,i) ; setSelected(i)} }
    style={{border : selected === i ? '1px solid red' : null}}   >{category}</button>
  );

  useEffect(() => {
    let categoryValue = localStorage.getItem("category") || "all";
    fetchValue(categoryValue)
    const select = localStorage.getItem("selected") || "";
    setSelected(select);
  }, []);

  return (
    <>

      <div className="header-bg">
        <h1 className="mb-3">News</h1>
        <div className="btns ">
          {Category.map((value,i) => {
            return <CategoryButton category={value} i={i}/>;
          })}
        </div>
      </div>

      

      <div className="news">
        <div className="container">
          <div className="row">
            {
              !loading
                ? <SpinnerLoad />
                :
                state.map((data, index) => {
                  return (
                    <NewsItem
                      imageUrl={data.imageUrl}
                      author={data.author}
                      title={data.title}
                      content={data.content}
                      date={data.date}
                      key={data.id}
                    />
                  );
                })
            }
          </div>
        </div>
      </div>
    </>
  );
};
export default App;

CodePudding user response:

According to the code looks like you want to display data specific to a category set when the user clicks on the category buttons. and after the click, the correct data is rendered and the current category button receives a change in its style highlighting it is the current state. I don't understand why you need to store anything in a client's localstorage, I would recommend storing too much in localStorage as it is limited and is used by different sites a user visits, I only store authentication tokens in localstorage and I believe that is the norm. I've tried to create the effect you want without the need to store in local storage

import React, { useState, useCallback, useEffect } from "react";
import ReactDOM from "react-dom";
import { cat } from "../categories.js";
import { news } from "../news.js";

function Example() {
  const [state, setState] = useState([]);
  const [loading, setLoading] = useState(false);
  const [selected, setSelected] = useState(null);

  useEffect(() => {
    function fetchFunction() {
      setLoading(true);
      for (let i = 0; i < news.length; i  ) {
        if (news[i].id === selected) {
          const current = news[i].c;
          setState(current);
        }
      }
      setLoading(false);
    }
    fetchFunction();
  }, [selected]);
  return (
    <>
      <ol
        style={{
          width: "50%",
          listStyle: "none",
          display: "flex",
          justifyContent: "space-between"
        }}
      >
        {cat.map((item, index) => {
          return (
            <li key={index}>
              <button
                style={{ border: selected === item.id && "none" }}
                onClick={() => {
                  setSelected(item.id);
                }}
              >
                {item.name}
              </button>
            </li>
          );
        })}
      </ol>
      <section style={{ width: "100%", height: "70%" }}>
        {state.map((item, index) => {
          return (
            <div
            key={index}
              style={{
                width: "30%",
                height: "30%",
                background: "red",
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                margin: "1% 0 2% 0"
              }}
            >
              {item.name}
            </div>
          );
        })}
      </section>
    </>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Example />, rootElement);

CodePudding user response:

You can save the selectedIndex in localStorage and retrieve it in the useEffect..

  const CategoryButton = ({ category, i  }) => (
    // passing index --> i to the fetch Value
    // setting selected as string instead of index for type checking 
    <button onClick={() =>{ fetchValue(category,i) ; setSelected(`${i}`)} }
    style={{border : selected === `${i}` ? '1px solid red' : null}}   >{category}</button>
  );
  
  const fetchValue = (category, index) => {
    localStorage.setItem("category", category);
    localStorage.setItem("selected", index);
   // ...
   }
   useEffect(() => {
   const select = localStorage.getItem("selected") || "";
   // passing selectedIndex to the fetchValue, otherwise it becomes 
   //undefined..
   fetchValue(categoryValue,select)
   setSelected(select);
   },[])
  • Related