数组上的React setState在调用后立即将值重置为空(功能组件)。

问题描述 投票:0回答:1

对不起,我问了这个问题,但经过一整天的研究,我仍然不明白为什么当我在数组上调用setState时,值会马上返回到null。我的代码工作了,然后我不得不把我的组件变成一个功能组件来使用MaterialUI,它停止工作。我试着使用useEffect,钩子中的值是好的,但之后马上又回到初始值。

(问题变量是markers,它总是回到[null,null])

是不是因为我存储了一个对象?

代码。

import React, { useState, useEffect } from 'react';
import $ from 'jquery'
import { makeStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';

import './app.css'
import Map from './Map'
import PlaceSearch from './PlaceSearch'
import { useReducer } from 'react';

function NewTrip () {
  const [mapCenter, setMapCenter] = useState([50.631290, 3.062750])
  const [markers, setMarkers] = useState([null, null])
  const [zoom, setZoom] = useState(13)

  // const initialState = {markers: [null, null]}
  // const [state, dispatch] = useReducer(reducer, initialState)

  // Load leaflet icons for markers
  const redIcon = new L.Icon({
    iconUrl: 'https://cdn.rawgit.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png',
    shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
    iconSize: [25, 41],
    iconAnchor: [12, 41],
    popupAnchor: [1, -34],
    shadowSize: [41, 41]
  });
  const blueIcon = new L.Icon({
    iconUrl: 'https://cdn.rawgit.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-blue.png',
    shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
    iconSize: [25, 41],
    iconAnchor: [12, 41],
    popupAnchor: [1, -34],
    shadowSize: [41, 41]
  }); 

  useEffect(() => {
    debugger
  })

  const departChanged = (e) => {
    var selectedPoint = e.suggestion.latlng
    var newMarkers = {...markers}

    newMarkers[0] = new L.marker(selectedPoint, {icon: blueIcon})
    setMapCenter([selectedPoint.lat, selectedPoint.lng])
    setMarkers(newMarkers)
    //dispatch({type: 'set_markers', payload: newMarkers})
    debugger
  }

  const arrivalChanged = (e) => {
    var selectedPoint = e.suggestion.latlng
    var newMarkers = {...markers}

    newMarkers[1] = new L.marker(selectedPoint, {icon: redIcon})
    setMapCenter([selectedPoint.lat, selectedPoint.lng])
    setMarkers(newMarkers)
  }

  //const classes = useStyles()

  return (
    <div>
      <h1 className="text-centered">Nouveau trajet</h1>
      <br/>
      <div className="split left">
        <div className="center">
          <PlaceSearch suggestionChanged={departChanged} placeholder={"Départ"} inputId={"departSearch"}></PlaceSearch>
          <PlaceSearch suggestionChanged={arrivalChanged} placeholder={"Arrivée"} inputId={"arrivalSearch"}></PlaceSearch>
          {/* <Map center={mapCenter} markers={markers} zoom={zoom}></Map> */}
        </div>
      </div>
      <div className="split right">
        <div className="center">
          <h2>Places disponibles</h2>
          <input id="seats" type="number" max="9" min="1" defaultValue="2"/>
          <p>(Min 1, Max 9)</p>
          <br/>
          <br/>
        </div>
      </div>
    </div>
  );
}

export default NewTrip;

如你所见,我甚至尝试用reducer代替state,但结果还是一样。

==== 更新 ======

好吧,经过研究,值是正确设置的,但是从dapartChanged和arrivateChanged函数里面访问时,值是不一样的,还是在函数外面。在函数外的值是正常的,在函数内的值总是Array[null, null]。

reactjs setstate
1个回答
0
投票

要改变一个现有数组中的特定元素,可以使用 setMarkers 你可以

const departChanged = (e) => {
  var selectedPoint = e.suggestion.latlng
  setMapCenter([selectedPoint.lat, selectedPoint.lng])
  setMarkers((prev) => [new L.marker(selectedPoint, {icon: blueIcon}), prev[1]])
}

const arrivalChanged = (e) => {
  var selectedPoint = e.suggestion.latlng
  setMapCenter([selectedPoint.lat, selectedPoint.lng])
  setMarkers((prev) => [prev[0], new L.marker(selectedPoint, {icon: redIcon})])
}

0
投票

你把标记分散到一个对象中,然后像调用一个数组一样调用它。

const arrivalChanged = (e) => {
    var selectedPoint = e.suggestion.latlng
    var newMarkers = {...markers} /*<==== should probably be const newMarkers = [...markers];*/

    newMarkers[1] = new L.marker(selectedPoint, {icon: redIcon})
    setMapCenter([selectedPoint.lat, selectedPoint.lng])
    setMarkers(newMarkers)
  }

如果还是不行,请 console.log(newMarkers) 使用前 setMarkers 所以我们可以看到数据是什么样子的。


0
投票

真正的问题是我从一个子组件中调用departChanged和arrivationChanged方法,显然在那个上下文中,我访问的所有值都是默认状态值。

我不知道如何解决这个问题,但目前我用useRef替换了它,它可以工作。

如果有人知道为什么当函数被其他组件调用时,状态值是默认值,请留言^^。

© www.soinside.com 2019 - 2024. All rights reserved.