@SuperDuperPuper

Почему при обновлении состояния не рендерится компонент?

arr и items имеют не одинаковые ссылки. React изменяет состояние items на arr, но почему-то не рендерит опять компонент.

const setSorted = (s) =>{
        setSort(s);
        //setItems((prev)=> prev.sort((a,b)=>a[s].localeCompare(b[s])));
        let arr = items.slice();
        arr.sort((a,b)=>a[s].localeCompare(b[s]));
        setItems(arr);
    }

const App = () => {

    const [items,setItems] = useState( [{key:"fwf1",title:"qfg",text:"JavaScript является объектно-ориентированным языком, имеющий типы и операторы, встроенные объекты и методы. Его синтаксис происходит от языков Java и C, поэтому много конструкций из эти text"},
              {key:"fgg1",title:"qfA",text:"some  основы любого языка: с типов данных. Программы на JavaScript оперируют значениями, и все эти значения принадлежат к определённому типу. Типы данных в JavaScript:"},
              {key:"gr21",title:"4AA",text:"Да, ещё Undefined и Null, которые немного обособлены. И Массивы, которые являются особым видом объектов. А также Даты и Регулярные выражения, тоже являющиеся объектами. И, если быть технически точным, функции это тоже особый вид объекта. Поэтому схема типов выглядит скорее так: text"},
              {key:"ftu1",title:"0AB",text:"Вы можете преобразовать строку в целое число, используя встроенную функцию parseInt(). Её необязательный второй параметр — основание системы счисления, которое следует всегда явно указывать: text"},
              {key:"23u1",title:"AAA",text:"Это случилось потому, что функция parseInt() расценила строку как восьмеричную из-за начального 0, а шестнадцатеричную - из-за начального ."}]
    );
    const [sort,setSort] = useState("");

    const setSorted = (s) =>{
        setSort(s);
        //setItems((prev)=> prev.sort((a,b)=>a[s].localeCompare(b[s])));
        let arr = items.slice();
        arr.sort((a,b)=>a[s].localeCompare(b[s]));
        setItems(arr);
    }


    const effect = useEffect(()=>{console.log("изменены-");console.log(items);},[items]);

    return (
        <div>
            <SearchSort sort={sort} setSort={setSorted}/>
            <ElementsList arr={items}/>
      </div>
    );
}

export default App;

import { Element } from "./Element";
export const ElementsList = ({arr}) =>{

    const [items,setItems]  = useState([...arr]);
    
    const onDelete = (index) => {
        let array = [...items];
        array.splice(index,1);
        setItems(array);
    }

    return (
        <ul style={{margin:"0 auto 0 auto",margin:"0 1em 0 1em"}}>
            {
                items.length !== 0?
                items.map((el,index)=><Element
                    index={index}
                    key={el.key}
                    item={el}
                    onDelete={onDelete}
            />):
                <p>Нет элементов!</p>
            }
        </ul>
    )
}

import { SelectCust } from "./UI/SelectCust";
export const SearchSort = ({sort,setSort}) => {
    const options = [{title:"По названию", value:"title"},{title:"По описанию",value:"text"}];
    return (
        <div style={{margin:"1em 0 1em 3.5em"}}>
            <input></input>
            <br/>
            <SelectCust title={"Сортировка"} options={options} sort={sort} setSort={setSort}/>
        </div>
    )
}

export const SelectCust = ({title,options,sort,setSort}) =>{

    const onSelected = (e) =>{
        setSort(e.target.value);
    }

    return(
        <select onChange={onSelected} value={sort}>
            <option value={""}  disabled = {true}>{title}</option>
            {options.map((el,index)=>{
                return <option value={el.value} key={index}>
                {el.title}
                </option>;
            })
            }
        </select> 
    )
}
  • Вопрос задан
  • 116 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
Не выдумывайте, всё рендерится.

Почему видимых изменений нет? Потому что обновляете одно состояние, а рендер выполняете на основе другого, items в App и items в ElementsList - это разные массивы. Не надо никакого useState в ElementList, выполняйте рендер на основе prop'а; метод onDelete перенесите в App и тоже передавайте в ElementList через props.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы