简体   繁体   中英

Trigger rerender of Functional React Component when Select Option Value is changed

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.

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