I have some radio buttons which are setting the rate type that I use with clients. This works as far as choosing one, and it sets that value. However, the next time I load this data, it does not render the button that was previously chosen as selected. It looks to me like I have it setup exactly the same way as I have it working in other code. So I'm sure it's something simple, but I can't seem to find it.
Once I click the buttons, they do render the correct one as selected and change the value in the database as expected. But as I said, when I load this again, it does bring in the data and set the state with the correct value through the function getRateType()
.
It just doesn't show which button is selected. My assumption is it's something to do with that I set the state initially to "", but why doesn't it update when I change the state to the correct value?
import React, { Component } from 'react';
import { Row, Col, Form, Modal, Button, Jumbotron, Table} from 'react-bootstrap';
import { config } from '../../Config/Constants';
import debounce from 'lodash.debounce';
const API_URL = config.url.API_URL;
class Project extends Component {
constructor(props) {
super(props);
this.state = {
rateType: ""
}
}
componentDidMount() {
this.getRateType(this.props.billProjId);
}
getRateType = (projId) => {
fetch(API_URL `/billingcalculator/projects/${projId}`)
.then((res) => {
if (!res.ok) {
throw new Error()
}
return res.json()
})
.then((result) => {
this.setState({ rateType: result[0].project_type });
console.log(this.state.rateType); <-- this shows the correct value
})
.catch((error) => {
console.log(error);
})
}
handleCheck = (e) => {
this.setState({ [e.target.name]: e.target.value },
() => this.updateDB())
}
updateDB = debounce(() => {
let data = {
rateType: this.state.rateType
};
this.updateRateType(data);
}, 1500);
updateRateType(data) {
fetch(API_URL `/billingcalculator/project/update`, {
method: "PUT",
body: JSON.stringify({
projectId: this.props.billProjId,
data: data,
}),
headers: { "Content-Type": "application/json" },
})
.then((res) => {
if (!res.ok) {
throw new Error();
}
return res.json();
})
.catch((err) => console.log(err))
.then(this.renderAgain());
}
render() {
return (
<div>
<Jumbotron className="mt-3">
<h1 className='display-4'>Project: {this.props.projectName}</h1>
<p>Project ID:{this.props.billProjId}</p>
<Form>
<Form.Group
as={Row}
name="rateType"
controlId="rateType"
onChange={this.handleCheck}
>
<Form.Check
inline
label="profit"
name="rateType"
type="radio"
id="rateType-profit"
value="profit"
defaultChecked={this.state.rateType === "profit"}
/>
<Form.Check
inline
label="non-profit"
name="rateType"
type="radio"
id="rateType-non-profit"
value="non-profit"
defaultChecked={this.state.rateType === "non-profit"}
/>
<Form.Check
inline
label="existing-client"
name="rateType"
type="radio"
id="rateType-existing"
value="existing"
defaultChecked={this.state.rateType === "existing"}
/>
</Form.Group>
</Form>
</Jumbotron>
</div>
)
}
}
export default Project;
CodePudding user response:
Use checked
instead of defaultChecked
if your checkbox is going to be updated after a component re-render
render() {
return (
<div>
<Jumbotron className="mt-3">
<h1 className='display-4'>Project: {this.props.projectName}</h1>
<p>Project ID:{this.props.billProjId}</p>
<Form>
<Form.Group
as={Row}
name="rateType"
controlId="rateType"
onChange={this.handleCheck}
>
<Form.Check
inline
label="profit"
name="rateType"
type="radio"
id="rateType-profit"
value="profit"
checked={this.state.rateType === "profit"}
/>
<Form.Check
inline
label="non-profit"
name="rateType"
type="radio"
id="rateType-non-profit"
value="non-profit"
checked={this.state.rateType === "non-profit"}
/>
<Form.Check
inline
label="existing-client"
name="rateType"
type="radio"
id="rateType-existing"
value="existing"
checked={this.state.rateType === "existing"}
/>
</Form.Group>
</Form>
</Jumbotron>
</div>
)
}