I studying The Odin Project and try to code CV app ( https://www.theodinproject.com/paths/full-stack-javascript/courses/javascript/lessons/cv-application ). I complete Bio part (name, phone, email). I understand that Job experince and Education components mostly the same. So i try to code Job experience component. In my App component i declare method to add another job (addJob method), and method to update state of App according to data in Job component with right id. To update this data in app i specified unique id to each job component. What is the best practise to code handleJobChange method?
I try to send data to my parent component from child.
App Component
import React from 'react';
import Bio from './components/Bio'
import CV from './components/CV'
import Job from './components/Job'
class App extends React.Component {
constructor() {
super()
this.handleBioChange = this.handleBioChange.bind(this)
this.idGen = this.idGen.bind(this)
this.handleJobChange = this.handleJobChange.bind(this)
this.state = {
bio_state: {name:'', phone:'', email:''},
job: [{id:this.idGen(), company:'', position:'',tasks:'', start:'', until:''}]
}
}
idGen() {
return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10);
}
handleBioChange = (e) => {
this.setState({
bio_state: Object.assign(this.state.bio_state,{[e.target.name]: e.target.value})
})
}
addJob = () => {
this.setState(this.state.job.concat([
{id:this.idGen(), company:'', position:'',tasks:'', start:'', until:''}
]))
}
handleJobChange = (e, id) => {
this.setState(previousState => {
console.log(e.target)
console.log("id is ",id)
let job = [...previousState.job]
console.log(job)
let indexOfJob = job.findIndex(job => job.id === id)
console.log(indexOfJob)
job[indexOfJob] = {...job[indexOfJob], [e.target.name]: e.target.value}
return { job }
})
}
render() {
console.log('app state', this.state.bio_state)
return (
<div>
<Bio onBioChange={this.handleBioChange} />
{
this.state.job.map((item) => (
<Job id={item.id} onJobChange={this.handleJobChange}/>
))
}
<CV name={this.state.bio_state.name} phone={this.state.bio_state.phone} email={this.state.bio_state.email} jobs={this.state.job}/>
</div>
)
}
}
child component
import React from 'react'
class Job extends React.Component{
constructor(props){
super(props)
}
render(){
const id = this.props.id
return(
<div id={this.props.id}>
<label for='company'>Company:</label>
<input name='company' onChange={(id=this.props.id)=>this.props.onJobChange(id)}></input>
<label for='position'>Position:</label>
<input name='position' onChange={()=>this.props.onJobChange(id)}></input>
<label for='tasks'>Tasks:</label>
<input name='tasks' onChange={()=>this.props.onJobChange(this.props.id)}></input>
<label for='start'>Date from:</label>
<input name='start' onChange={()=>this.props.onJobChange(this.props.id)}></input>
<label for='until'>Date until:</label>
<input name='until' onChange={()=>this.props.onJobChange(this.props.id)}></input>
</div>
)
}
}
export default Job
I dont know what to do, seems like I incorrect use function in my child component with parameters. Please help? I'am desperate =(
I figure it out. I change my app component handleJobChange method like so
handleJobChange = (id, key,value) => {
this.setState(previousState => {
console.log("id is ", id)
console.log("key is ", key)
console.log("val is ", value)
let job = [...previousState.job]
console.log(job)
let indexOfJob = job.findIndex(job => job.id === id)
console.log(indexOfJob)
job[indexOfJob] = {...job[indexOfJob], [key]: value}
return { job }
})
}
And in my Job component i change like so
class Job extends React.Component{
constructor(props){
super(props)
this.handleChange = this.handleChange.bind(this)
}
handleChange=(e)=>{
const key = e.target.name
const value = e.target.value
const id = this.props.id
this.props.onJobChange(id, key, value)
}
render(){
const id = this.props.id
return(
<div id={this.props.id}>
<label for='company'>Company:</label>
<input name='company' onChange={this.handleChange}></input>
<label for='position'>Position:</label>
<input name='position' onChange={this.handleChange}></input>
<label for='tasks'>Tasks:</label>
<input name='tasks' onChange={this.handleChange}></input>
<label for='start'>Date from:</label>
<input name='start' onChange={this.handleChange}></input>
<label for='until'>Date until:</label>
<input name='until' onChange={this.handleChange}></input>
</div>
)
}
}
And its worked !
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.