【问题标题】:useState does not update the stateuseState 不更新状态
【发布时间】:2020-02-18 10:12:12
【问题描述】:

我正在尝试使用 useState 挂钩更新状态,但状态不会更新。我已经检查过如何修复它,但真的不知道是什么原因导致了这一点。这是我没有包含 url 和导入文件的整个代码...

当 onchange 方法触发 ilceZoom 函数事件有值时,我可以得到它

const ilceUrl = 'URL';


const AddressSearchMaks = (props) => {
    useEffect(() => {
        ilceLoad();
    }, []);

    const [ ilceler, setIlceler ] = useState([]);
    const [ selectedIlce, setSelectedIlce ] = useState(null);


    let queryTask;
    let query;
    let sfs;
    let lineSymbol;
    let polygon;
    let polyline;
    let graphic;
    let extent;
    let point;
    let wMercatorUtils;
    let rfConverter;

    loadModules([
        'esri/tasks/query',
        'esri/tasks/QueryTask',
        'esri/symbols/SimpleFillSymbol',
        'esri/symbols/SimpleLineSymbol',
        'esri/geometry/Polygon',
        'esri/geometry/Polyline',
        'esri/geometry/webMercatorUtils',
        'esri/geometry/Extent',
        'esri/geometry/Point',
        'esri/graphic',
        'esri/Color',
        'libs/ReferenceConverter'
    ]).then(
        (
            [
                Query,
                QueryTask,
                SimpleFillSymbol,
                SimpleLineSymbol,
                Polygon,
                Polyline,
                webMercatorUtils,
                Extent,
                Point,
                Graphic,
                Color,
                referenceConverter
            ]
        ) => {
            queryTask = QueryTask;
            query = Query;
            polygon = Polygon;
            polyline = Polyline;
            graphic = Graphic;
            extent = Extent;
            point = Point;
            wMercatorUtils = webMercatorUtils;
            rfConverter = referenceConverter;
            sfs = new SimpleFillSymbol(
                SimpleFillSymbol.STYLE_SOLID,
                new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([ 0, 255, 255 ]), 4),
                new Color([ 140, 140, 140, 0.25 ])
            );
            lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([ 0, 255, 255 ]), 4).setWidth(4);
        }
    );

    const getAdres = async (url) => {
        let response = await fetch(url);
        let data = await response.json();
        let list = [];
        data.AdresList.Adresler.Adres.forEach((item) => {
            list.push({
                label: item.ADI,
                value: item.ID,
                lat: item.LAT,
                lon: item.LON
            });
        });
        return list;
    };

    async function ilceLoad() {
        let ilceList = await getAdres(ilceUrl);
        setIlceler(ilceList);
    }

    const convertExtent = (lat, lon) => {
        let p;
        let ext;
        const sr = props.map.spatialReference;
        if (sr.wkid == 102100) {
            const _p = wMercatorUtils.lngLatToXY(lon, lat);
            ext = extent({
                xmin: _p[0],
                ymin: _p[1],
                xmax: _p[0],
                ymax: _p[1],
                spatialReference: props.map.spatialReference
            });
        } else {
            const res = rfConverter.WgsToItrf(lat, lon);
            ext = extent({
                xmin: res.x,
                ymin: res.y,
                xmax: res.x,
                ymax: res.y,
                spatialReference: props.map.spatialReference
            });
            p = point(res.x, res.y);
        }
        p.spatialReference = sr;
        return ext;
    };

    const ilceZoom = (evt) => {
        setSelectedIlce(evt.value);
        console.log('selectedIlce', selectedIlce);
        setError(false);
        console.log('error', error);
        const qTask = queryTask(maksIlce);
        const q = query();
        q.returnGeometry = true;
        q.outFields = [ '*' ];
        q.outSpatialReference = { wkid: 5254 };
        q.where = `KIMLIKNO=${evt.value}`;
        qTask.execute(q, (evt) => {
            const polyGon = polygon({
                rings: evt.features[0].geometry.rings
            });
            props.map.graphics.add(graphic(polyGon, sfs));
        });
        const extent = convertExtent(evt.lat, evt.lon);
        props.map.setExtent(extent);
        mahalleLoad();
    };



    return (

            <Select name='adresSelect' options={ilceler} onChange={(e) => ilceZoom(e)} placeholder='İlçe Seçiniz' />

    );
};

const mapStateToProps = (state) => ({
    map: state.map.map
});

export default connect(mapStateToProps, null)(AddressSearchMaks);


【问题讨论】:

  • 您确定该事件具有价值吗?也许是 event.target.value?
  • 是的 evt.value 有值
  • 你能上传整个组件的代码吗?
  • 可以说当我在同一个地方更新它时,我确实有一个错误状态 setError(true) 它确实是更新它:( 但它不会更新 setSelectedIlce 的状态
  • 看起来不错。当我在ilceZoom() 下使用setSelectedIlce('deneme'); 时,它会将选定的 ilce 设置为“deneme”。不要与console.log('selectedIlce', selectedIlce); 这一行混淆,因为 setState 是异步工作的,所以它可以稍后完成 setState。

标签: reactjs react-hooks


【解决方案1】:

可能与某些环境绑定问题有关。尝试使用 setState 作为函数:

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

    const [ ilceler, setIlceler ] = useState([]);
    const [ selectedIlce, setSelectedIlce ] = useState(null);

async function ilceLoad() {
        let ilceList = await getAdres(ilceUrl);
        setIlceler(ilceList); // update the state, it works here 
    }

const ilceZoom = (evt) => {
        setSelectedIlce(prev => {
          console.log("prev: ", prev);
          console.log("evt.value: ", evt.value);
          return evt.value;
        }); 
        const qTask = queryTask(url);
        const q = query();
        q.returnGeometry = true;
        q.outFields = [ '*' ];
        q.outSpatialReference = { wkid: 5254 };
        q.where = `VARIABLE NAME=${evt.value}`;
        qTask.execute(q, (evt) => {
            const polyGon = polygon({
                rings: evt.features[0].geometry.rings
            });
            props.map.graphics.add(graphic(polyGon, sfs));
        });
        const extent = convertExtent(evt.lat, evt.lon);
        props.map.setExtent(extent);
    };

【讨论】:

  • 仍然值为 null :(
  • 尝试注销 prev 和 setState 范围内的 evt.value,如:setSelectedIlce(prev =&gt; { console.log("prev: ", prev); console.log("evt.value: ", evt.value); return evt.value; })
  • prev: null, evt.value: 1739 仍然无法更新状态
  • 我猜你的状态更新了正确的,但显示或重用可能有一些错误
  • 如果它记得第 2 次第 1 次更改,你能连续更新 2 次吗?
【解决方案2】:

你可以这样试试。因为,在您的代码中,您在 selectedIlce 中设置数据,但在重新渲染之前,您尝试检查控制台中的值,所以最好在事件函数之外使用您的控制台,这样当它更新时,它会反映在控制台中。

    console.log('selectedIlce', selectedIlce);
    const ilceZoom = (evt) => {
       setSelectedIlce(evt.value);
       ....
    }

【讨论】:

    猜你喜欢
    • 2022-01-15
    • 2023-02-26
    • 2023-04-02
    • 2021-01-14
    • 1970-01-01
    • 2021-01-19
    • 2021-05-20
    • 1970-01-01
    • 2020-11-22
    相关资源
    最近更新 更多