简体   繁体   中英

Error: Objects are not valid as a React child, prop not returning in React Hook

I am receiving an error when trying to return ( <div id="info_side">{info}</div> ) below. I have a _onClick function that works and I can console log info if I do not include {info} anywhere in the return. How can I fix this?

Here is the error: Error: Objects are not valid as a React child (found: object with keys {type, _vectorTileFeature, properties, layer, source, state}). If you meant to render a collection of children, use an array instead. Error: Objects are not valid as a React child (found: object with keys {type, _vectorTileFeature, properties, layer, source, state}). If you meant to render a collection of children, use an array instead.

Update Had to convert the object to an array and then map the key values and it now works.

const _onClick = event => {
  const display = event.features;
  if (display.length > 0) {
    setInfo(display[0].properties)
  }
}

var list = Object.entries(info).map(([key,value]) => {
  return (
    <div><span className="bold">{key}</span>: <span>{value.toString()}</span></div>
  )
});

return (
    <div id="info_side">{list}</div>
)

Original Post

const App = () => {
    const [viewport, setViewport] = useState({longitude: -98.58, latitude: 39.83, zoom: 3.5})
    const [locations, setLocations] = useState([])
    const [geojson, setGeojson] = useState(null)
    const [size, setSize] = useState({value: "All"})
    const [info, setInfo] = useState([]) 

    useEffect(() => {
        setLocations(geodata)
        _updateLocationData(size.value)
    }, [locations]);

    useEffect(() => {
        setInfo(info);
    }, [info]);

    const _updateViewport = viewport => {
        setViewport(viewport)
    }

    const _updateData = event => {
        setSize({value: event.target.value})
        _updateLocationData(event.target.value)
    }

    const _updateLocationData = (sizeValue) => {   
        var tempLocations = [];
        locations.forEach(function(res) {
            if (sizeValue === "All") {
                tempLocations.push(res);
            } else if (res.Size === sizeValue) {
                tempLocations.push(res);
            }
        });
        var data = {
            type: "FeatureCollection",
            features: tempLocations.map(item => {
                return {
                    id: ...,
                    type: "Feature",
                    properties: {
                        Company: item.Company,
                        Address: item.Address,
                        Phone: item.Phone,
                        Long: item.Long,
                        Lat: item.Lat,
                        Size: item.Size,
                    },
                    geometry: {
                        type: "Point",
                        coordinates: [item.Long, item.Lat]
                    }
                };
            })
        };
        setGeojson(data);
    }

    const _onClick = event => {
        const { features } = event;
        const info = features && features.find(f => f.layer.id === 'icon');
        setInfo(info); // Error: Objects are not valid as a React child (found: object with keys {type, _vectorTileFeature, properties, layer, source, state}). If you meant to render a collection of children, use an array instead.
        console.log(info) // I can see the object with no error here if I do not add {info} in return ( <div id="info_side">{info}</div> )
    }

    return (
      <div className="App">
        <div className="inner-left map-container">
          <ReactMapGL
                {...viewport}
                onViewportChange={_updateViewport}
                width="100%"
                height="100%"
                mapStyle={mapStyle}
                mapboxApiAccessToken={TOKEN}
                onClick={_onClick}>

                <Source id="my-data" type="geojson" data={geojson}>
                    <Layer {...icon} />
                </Source>

                <div style={navStyle}>
                  <NavigationControl onViewportChange={_updateViewport} />
                  <select onChange={_updateData} defaultValue={size.value}>
                      <option value="All">All</option>
                      <option value="Large">Large</option>
                      <option value="Medium">Medium</option>
                      <option value="Small">Small</option>
                      <option value="Very Small">Very Small</option>
                  </select>
              </div>
          </ReactMapGL>
        </div>
        <div className="inner-right info-container">
          <Nav />
          <Search />
          <div id="info_side"> // where is error is thrown if I have {info} below
            <div className="company">{info.properties.Company}</div> 
            <div className="address">{info.properties.Address}</div>
            <div className="phone">{info.properties.Phone}</div>
          </div>
        </div>
      </div> 
    );
}

export default App;

Info is an object, so you can't do this:

<div id="info_side">{info}</div>

Every time you use {} inside a DOM elemnet in React, the variable inside {} must a string, number or boolean. So you have to make sure you are using a primitive inside brackets.

Try {JSON.stringify(info)} or any variable you want and you'll see what is the string represtabntion of that value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM