【问题标题】:reactjs useState: select onChange triggers setState but component doesn't re-renderreactjs useState:选择onChange触发setState但组件不会重新渲染
【发布时间】:2021-08-04 15:41:34
【问题描述】:

我正在尝试使用 react 中的选择下拉菜单按属性对对象数组进行排序。

使用 useState() 挂钩在父容器中定义数据,并且我将 onSortChange 函数向下传递给子选择组件 DataSelector。数据由另一个组件 DataList 显示为列表。下面演示的最小示例(为简洁起见减去导入):

  1. 父容器:
const ParentContainer = () => {

    const [data, setData] = useState([]);

    useEffect( () => {
        populateData();
    }, []);

    function populateData() {
        const dave = {first_name: 'David', last_name: 'Taylor',
                    age: 25, salary: 25000};
        
        const bob = {first_name: 'Robert', last_name: 'Bush',
                    age: 31, salary: 30000};

        const sue = {first_name: 'Susan', last_name: 'Harman',
                    age: 22, salary: 28000};

        setData([dave, bob, sue]) 
    };

    const onSortChange = function(property) {
        setData(data.sort(propertySort(property)));
    };

    // sort by object property value (works for strings or )
    const propertySort = (prop) => {
        return function(a, b) {
            return (a[prop] < b[prop]) ? -1 : (a[prop] > b[prop]) ? 1 : 0;
        };
    };

    return (
        <>
            <DataSelector onSortChange={onSortChange} />
            <DataList data={data}/>
        </> 
    );
};

2:数据选择器组件

const DataSelector = ({onSortChange}) => {

    const handleChange = function(event) {
        onSortChange(event.target.value);
    }

    return (
        <select onChange={handleChange}>
            <option value="first_name">Name</option>
            <option value="age">Age</option>
            <option value="salary">Salary</option>
        </select>
    );
};

export default DataSelector;

当我更改选择选项时,handleChange 会正确触发,如果我在父容器中 console.log “数据”,它会正确返回按从 handleChange 传递的值排序的数组。但是,DataList 组件不会重新呈现列表项。

在调用数据的 setState 函数后,我需要采取其他步骤来重新渲染 DataList 吗?

【问题讨论】:

    标签: javascript reactjs use-state


    【解决方案1】:

    我相信您需要将数据设置为新的东西,而 data.sort() 是同一个数组。如果您克隆数据,然后将排序后的克隆传递给 setData 我认为它应该可以工作。

    【讨论】:

      【解决方案2】:

      我认为您需要使用扩展运算符才能正确更新状态

      尝试如下:-

      setData([...data.sort(propertySort(property))]);
      

      【讨论】:

      • 是的,就是这样。下面@Andrew 的回答也是正确的。我忘了你必须重新分配给一个新的数组。谢谢两位!
      【解决方案3】:

      sort() 方法对数组中的项进行排序。除了返回排序后的数组外,它还改变了原始数组中元素的位置。

      所以 setData 不会改变值。使用以下任一方法来解决您的问题。

      setData(data.slice().sort(propertySort(property)));
      

      setData([...data.sort(propertySort(property))]);
      

      或者

      setData([...data].sort(propertySort(property)));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-02
        • 2020-10-29
        • 1970-01-01
        • 2021-12-06
        • 2016-09-09
        • 2020-01-26
        • 1970-01-01
        相关资源
        最近更新 更多