I am new to react and working on a Functional Component that should be re-rendered when the value of a Select Menu is changed. The code I´ve implemented so far doesn´t do the trick. The SelectInput Component is used in the Overlay Component; here´s my Functional Component so far:
import React, {useEffect, useState, useReducer, useLayoutEffect} from 'react';
import "./formstyles.css";
//i18n
import {withNamespaces} from 'react-i18next';
import { withRouter } from "react-router-dom";
const SelectAddressComponent = (props) => {
const [loading, setLoading] = useState(true);
const [, forceUpdate] = useReducer(x => x + 1, 0);
const [error, setError] = useState('');
const [data, setData] = useState([]);
const [formattedaddress, setAddress] = useState([])
const useForceUpdate = () => useState()[1];
const selectedValue = props.selectedValue;
console.log('Adresse', selectedValue)
let usersWithName = Object.keys(data).map(function(key) {
JSON.stringify(data);
let newArr = Object.keys(data);
let mappedArr = newArr.map(function (i) {
return [i, data[i]];
})
let formattedaddress = mappedArr[18];
return formattedaddress
});
useEffect(() => {
setAddress(
usersWithName
)
},[])
/* useLayoutEffect(() => {
let a = document.getElementsByClassName('address-select');
a.addEventListener('change', forceUpdate);
console.log('useLayouteffect ===>')
return () => window.removeEventListener('selectionchange', forceUpdate);
}, []);
*/
useEffect(() => {
setLoading(true);
fetch('http://tpservice:8888/api/v1/address')
.then((response) => response.json())
.then((data) => {
setLoading(false);
setData(data);
})
.catch((e) => {
setLoading(false);
setError('fetch failed');
});
}, []);
if (loading) {
return <span>loading..</span>;
}
if (error !== '') {
return <>ERROR: {error}</>;
}
return (
<React.Fragment>
<div className="clearfix">
<div className="float-left">
<div className="input-group input-group-sm">
<div className="input-group-append">
<label className="input-group-text">Adresse</label>
</div>
<select name="default_address_id" data-value={props.selectedValue} onChange={props.onChange} className="custom-select custom-select-sm">
{data.map((element) => (
<option value={element.id} selected={element.id==props.selectedValue ? true : false}> {element.formattedaddress}</option>
))}
</select>
</div>
</div>
</div>
</React.Fragment>
);
}
export default withRouter(withNamespaces()(SelectAddressComponent));
This is the Component where the Select Component is incorporated:
import React, {Component, useContext, useEffect, useRef, useState} from 'react';
import "./formstyles.css";
import {
Row,
Col,
Card,
CardBody,
CardTitle,
CardSubtitle,
Nav,
NavItem,
TabPane,
CardText, NavLink, TabContent
} from "reactstrap";
//i18n
import {withNamespaces} from 'react-i18next';
//Import Breadcrumb
import { withRouter } from "react-router-dom";
import classnames from "classnames";
import EmployeesList from "../../pages/Employees/employees-list";
import EmployeeIdComponent from "./EmployeeId";
import EmployeeId from "./EmployeeId";
import MapsComponent from "./MapsComponent";
import SelectAddressComponent from "./SelectAddressComponent";
const OverlayComponent = (props) => {
const nameForm = useRef(null)
const [employeeIdInOverlay, setEmployeeInOverlay] = useState()
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const [data, setData] = useState('');
const [customActiveTab, setcustomActiveTab] = useState("1");
const [activeTabJustify, setactiveTabJustify] = useState("5");
function useForceUpdate(){
const [value, setValue] = useState(0); // integer state
return () => setValue(value => ++value); // update the state to force render
}
console.log('employeeId in Form Component',props);
const [formData, setFormData] = useState({
firstname: "",
lastname: "",
email: "",
address: "",
performance_index: "",
min_customer_distance:"",
customer_distance_radius:"",
employeeId: "",
default_address_longitude: "",
default_address_latitude: "",
resource_id: "0",
users: []
});
const [payload, setPayload] = useState({});
const updateFormDataOld = e => {
const {name, value} = e.target;
console.log(name, value);
setFormData({
...formData,
[name]: value
})
console.log(payload);
}
const updateFormData = e => {
const {name, value} = e.target;
console.log(name, value);
setPayload({
...payload,
[name]: value
})
setFormData({
...formData,
[name]: value
})
console.log(payload, 'Reload');
}
useEffect(() => {
setLoading(true);
fetch('http://tpservice:8888/api/v1/employee/' + props.employeeId)
.then((response) => response.json())
.then((data) => {
setLoading(false);
setFormData(data);
console.log(data,'Data Objekt');
})
.catch((e) => {
setLoading(false);
setError('fetch failed');
});
}, []);
if (loading) {
return <span>loading..</span>;
}
if (error !== '') {
return <span>ERROR: {error}</span>;
}
const submit = e => {
e.preventDefault();
const {employeeId} = props;
console.log('employeeId', employeeId)
fetch(`http://tpservice:8888/api/v1/employee/` + employeeId, {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
...payload
}),
}).then(res => res.json())
.then(res => {
console.log('res from update', res)
}).catch(err => {
console.log('an error occurred', err)
})
}
function toggleCustomJustified(tab) {
if (activeTabJustify !== tab) {
setactiveTabJustify(tab);
}
}
return (
<div className="overlay">
<Card>
<CardBody>
<CardTitle>Adresse</CardTitle>
<h3>Mitarbeiterinformationen aktualisieren</h3>
<CardSubtitle className="mb-3">
</CardSubtitle>
<Nav tabs className="nav-tabs-custom nav-justified">
<NavItem>
<NavLink
style={{cursor: "pointer"}}
className={classnames({
active: activeTabJustify === "5"
})}
onClick={() => {
toggleCustomJustified("5");
}}>
<span className="d-none d-sm-block">Daten</span>
</NavLink>
</NavItem>
<NavItem>
<NavLink
style={{cursor: "pointer"}}
className={classnames({
active: activeTabJustify === "6"
})}
onClick={() => {
toggleCustomJustified("6");
}}>
<span className="d-none d-sm-block">Adresse</span>
</NavLink>
</NavItem>
<NavItem>
<NavLink
style={{cursor: "pointer"}}
className={classnames({
active: activeTabJustify === "7"
})}
onClick={() => {
toggleCustomJustified("7");
}}>
<span className="d-none d-sm-block">Karte</span>
</NavLink>
</NavItem>
<NavItem>
<NavLink
style={{cursor: "pointer"}}
className={classnames({
active: activeTabJustify === "8"
})}
onClick={() => {
toggleCustomJustified("8");
}}
>
<span className="d-none d-sm-block">tba</span>
</NavLink>
</NavItem>
</Nav>
<TabContent activeTab={activeTabJustify}>
<TabPane tabId="5" className="p-3">
<Row>
<Col sm="12">
<form ref={nameForm} onSubmit={submit}>
<input
type="text"
name="performance_index"
value={formData.performance_index}
onChange={formData => updateFormData(formData)}
placeholder={props.t('Enter Performance Index')}
/>
<br/>
<input
type="text"
name="min_customer_distance"
value={formData.min_customer_distance}
onChange={e => updateFormData(e)}
placeholder={props.t('Enter Min. Customer Distance')}
/>
<br/>
<input
type="text"
name="customer_distance_radius"
value={formData.customer_distance_radius}
onChange={e => updateFormData(e)}
placeholder={props.t('Enter Customer Distance Radius')}
required
/>
<br/>
<input
value={formData.firstname}
onChange={updateFormData}
placeholder={props.t('Enter Firstname')}
type="text"
name="firstname"
required
/>
<br/>
<input
value={formData.lastname}
onChange={updateFormData}
placeholder={props.t('Enter Lastname')}
type="text"
name="lastname"
required
/>
<br/>
<input
value={formData.email}
onChange={e => updateFormData(e)}
placeholder={props.t('Enter Email')}
type="email"
name="email"
required
/>
<input
value={data.default_address_latitude}
onChange={e => updateFormData(e)}
placeholder={props.t('default_address_latitude')}
type="number"
name="number"
/>
<input
value={data.default_address_longitude}
onChange={e => updateFormData(e)}
placeholder={props.t('default_address_longitude')}
type="number"
name="number"
/>
<br/>
<SelectAddressComponent onChange={e => updateFormData(e)}
selectedValue={formData.default_address_id}></SelectAddressComponent>
<br/>
<button type="submit">{props.t('Submit')}</button>
</form>
</Col>
</Row>
</TabPane>
<TabPane tabId="6" className="p-3">
<Row>
<Col sm="12">
<CardText>
</CardText>
</Col>
</Row>
</TabPane>
<TabPane tabId="7" className="p-3">
<Row>
<Col sm="12">
<CardText>
<MapsComponent default_address_latitude={formData.default_address_latitude}
default_address_longitude={formData.default_address_longitude}>
</MapsComponent>
</CardText>
</Col>
</Row>
</TabPane>
<TabPane tabId="8" className="p-3">
<Row>
<Col sm="12">
<CardText>
Trust fund seitan letterpress, keytar raw denim
keffiyeh etsy art party before they sold out master
cleanse gluten-free squid scenester freegan cosby
sweater. Fanny pack portland seitan DIY, art party
locavore wolf cliche high life echo park Austin.
Cred vinyl keffiyeh DIY salvia PBR, banh mi before
they sold out farm-to-table VHS viral locavore cosby
sweater. Lomo wolf viral, mustache readymade
thundercats keffiyeh craft beer marfa ethical. Wolf
salvia freegan, sartorial keffiyeh echo park vegan.
</CardText>
</Col>
</Row>
</TabPane>
</TabContent>
</CardBody>
</Card>
</div>);
}
export default withRouter(withNamespaces()(OverlayComponent));
Any hints or help would be very much appreciated, thanks in advance
Set the value of the select in State. By updating State, react automatically updates the components that use the State.
Example: https://learn.co/lessons/react-updating-state (Right below the first code example)
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.