How to add a new component with each input? - reactjs

I have a form. When I enter something there and click on "submit", I want my app to add a new component which must include this one input everytime when I click on "submit".
export default class AddForm extends Component{
constructor(props){
super(props);
this.state = {
input: '',
obj: [],
}
this.onHandleChange = this.onHandleChange.bind(this);
this.onHandleSubmit = this.onHandleSubmit.bind(this);
}
onHandleChange(e){
this.setState({
input: e.target.value
});
}
onHandleSubmit(){
this.state.obj.push(this.state.input);
this.setState({
input: ''
})
}
render(){
return(
<div className = 'adder'>
<h1 className = 'header'>Enter the type of tasks you need to be done:</h1>
<div>
<form>
<input className = 'board-add' onSubmit = {this.onHandleSubmit} onChange = {this.onHandleChange} type = 'search' name = 'textarea' placeholder = 'How shall we call the board?'/>
<p><button className = 'cancel'>CANCEL</button>
<button onClick = {this.onHandleSubmit} className = 'create'>CREATE</button></p>
</form>
</div>
{this.state.obj.map((item) => <TaskBoard taskType = {item} />)}
</div>
);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

this.state.obj.push(this.state.input);
^ This is not good practice in React. instead do this
obj: [...this.state.obj, this.state.input],
For more information on ... stuff check out the link below
https://medium.com/coding-at-dawn/how-to-use-the-spread-operator-in-javascript-b9e4a8b06fab
also
You did not have a value prop on the input field, thus you wont be able to reset the field after submit is executed.
<input
className="board-add"
onSubmit={this.onHandleSubmit}
onChange={this.onHandleChange}
type="search"
name="textarea"
value={this.state.input}
placeholder="How shall we call the board?"
/>
codesandbox
https://codesandbox.io/s/adoring-elbakyan-69hth?file=/src/App.js:0-1459
Hope this answers your question.
AddForm.js
import React from "react";
import "./styles.css";
import TaskBoard from "./Taskboard";
export default class Addform extends React.Component {
constructor(props) {
super(props);
this.state = {
input: "",
arr: []
};
this.onHandleChange = this.onHandleChange.bind(this);
this.onHandleSubmit = this.onHandleSubmit.bind(this);
}
onHandleChange(e) {
this.setState({
input: e.target.value
});
}
onHandleSubmit(e) {
e.preventDefault();
this.setState({
arr: [...this.state.arr, this.state.input],
input: ""
});
}
render() {
console.log(this.state.arr);
return (
<div className="adder">
<h1 className="header">Enter the type of tasks you need to be done:</h1>
<div>
<form>
<input
className="board-add"
onSubmit={this.onHandleSubmit}
onChange={this.onHandleChange}
type="search"
name="textarea"
value={this.state.input}
placeholder="How shall we call the board?"
/>
<p>
<button className="cancel">CANCEL</button>
<button onClick={this.onHandleSubmit} className="create">
CREATE
</button>
</p>
</form>
</div>
{this.state.arr.map(item => (
<TaskBoard taskType={item} />
))}
</div>
);
}
}
Taskboard.js
import React from "react";
export default function TaskBoard(props) {
return <div style={{ color: "tomato" }}> {props.taskType}</div>;
}

Related

React state is udpate but not in the css doodle tag

The state of the app is ok. It is updating when I change a value in the textarea I can see the changement in the state component with the react utility but the css doodle don't update. I must refresh manually to see the changes I don't understand why. Thanks a lot
class App extends Component {
state ={
dood: doodText
}
componentDidMount(){
const dood=localStorage.getItem('dood')
if(dood){
this.setState({dood})
}
else{
this.setState({dood: doodText})
}
}
componentDidUpdate(){
const {dood}= this.state
localStorage.setItem('dood', dood)
}
handleChange = event =>{
var dood= event.target.value
this.setState({dood})
}
render(){
return (
<div className="container" onChange={this.handleChange} >
<div className="row">
<div className="col-sm-6">
<textarea onChange={this.handleChange} value={this.state.dood}
className="form-control"
rows="25" />
</div>
</div>
<div className="col-sm-6" onChange={this.handleChange} >
<css-doodle >{this.state.dood}</css-doodle>
</div>
<div>
</div>
</div>
);
}
}
export default App;
Just set some order
I think its should work, I add a div with dood inside to see if its work.
And I write some comment for you.
class App extends Component {
constructor() {
super();
this.handleChange = this.handleChange.bind(this);
}
state = {
dood: doodText
}
componentDidMount() {
const dood = localStorage.getItem('dood')
if (dood) {
this.setState({ dood })
}
// THIS ELSE DO NOT NECESSARY
// else {
// this.setState({ dood: doodText })
// }
}
componentDidUpdate() {
// FOR WHY IS THAT HAPPEN EVERY UPDATE?
const dood = this.state.dood
localStorage.setItem('dood', dood)
}
// USE BIND IS BETTER
handleChange(ev) {
var dood = ev.target.value
this.setState({ dood })
}
render() {
return (
<div className="container" >
<div className="row">
<div className="col-sm-6">
<textarea onChange={this.handleChange} value={this.state.dood}
className="form-control"
rows="25" />
</div>
</div>
<div>{dood}</div>
<div className="col-sm-6" >
<css-doodle >{this.state.dood}</css-doodle>
</div>
</div>
);
}
}
export default App;
css-doodle provides an .update() method to manually update it, see:
https://css-doodle.com/#js-api-update
So you can listen to the change or input event of the textarea and then call .update()

the Cardlist component is not getting called upon changing state

I'm new to react js and is having some problem in my code. I have a Cardlist component which is returning my contact list layout when i pass my contactlist into it. I added a searchbox to search for a particular contact. The list updated upon entering some text in search box (I logged it out in console and it is working finely). The render and return methods are also working well upon changing search text ( i.e they are getting called everytime after changing state, I logged them out) but the Cardlist component is not getting called again. It still shows the same old list. The console.log inside this cardlist component is also not logging anything which simply implies it is not called again.
Here is the main component (not whole code shown, only the necessary part) :
constructor(props){
super(props);
this.state = {
friendslist: this.props.data.friendslist,
searchfield:''
}
}
onSearchChange = (event) => {
this.setState({ searchfield: event.target.value });
}
render(){
var filterfriendslist = this.state.friendslist.filter(friendslistitem => {
return friendslistitem.name.toLowerCase().includes(this.state.searchfield.toLowerCase())
});
{console.log( filterfriendslist )}
return(
<div>
<input id="name" onChange={this.onSearchChange} className="input-reset ba b--black-20 pa2 mv2 db w-100 bg-near-white" type="text" placeholder='Search' />
<Scroll>
<div>
{console.log( filterfriendslist )}
<Cardlist friendlist={ filterfriendslist } loadChattingUser={ this.loadChattingUser } />
</div>
</Scroll>
</div>
);
}
}
export default Contacts;
Here is the Carlist component :
import React from 'react';
import Card from './Card';
class Cardlist extends React.Component {
constructor(props){
super(props);
console.log("Clicked");
}
cardComponent = this.props.friendlist.map((user, i) => {
return <Card key={i} id={this.props.friendlist[i].id} name = {this.props.friendlist[i].name} imageURL={this.props.friendlist[i].imageurl} email={this.props.friendlist[i].email} msgDatabase={ this.props.friendlist[i].msgdata } loadChattingUser={ this.props.loadChattingUser } />
})
render(){
return (
<div>
{this.cardComponent}
</div>
);
}
}
export default Cardlist;
Here is the card component :
import React from 'react';
class Card extends React.Component {
constructor(props){
super(props);
this.state = {
name: this.props.name,
imageURL: this.props.imageURL,
email: this.props.email,
msgDatabase: this.props.msgDatabase
}
}
fillChat = () => {
this.props.loadChattingUser(this.state);
}
render(){
return (
<div className="dt w-100 bb b--black-05 pb2 mt2 pa2 bg-near-white pointer" onClick={ this.fillChat }>
<div className="dtc w2 w3-ns v-mid">
<img alt="Profile" src={this.props.imageURL} className="ba b--black-10 db br-100 w2 w3-ns h2 h3-ns"/>
</div>
<div className="dtc v-mid pl3">
<h1 className="f6 f5-ns fw6 lh-title black mv0">{this.props.name}</h1>
<h2 className="f6 fw4 mt0 mb0 black-60">{this.props.email}</h2>
</div>
<div className="dtc v-mid">
<form className="w-100 tr">
<button className="f6 button-reset bg-white ba b--black-10 dim pointer pv1 black-60" type="submit">+ Follow</button>
</form>
</div>
</div>
);
}
}
export default Card;
I want the Cardlist layout to change according to input in the search but it remain same as the initial list
The issue on your implementation of Cardlist. In your implementation cardComponent field is precomputed field. It supposed to be like this:
class Cardlist extends React.Component {
constructor(props) {
super(props);
console.log("Clicked");
}
render() {
const cardComponent = this.props.friendlist.map((user, i) => {
return (
<Card
key={i}
id={this.props.friendlist[i].id}
name={this.props.friendlist[i].name}
imageURL={this.props.friendlist[i].imageurl}
email={this.props.friendlist[i].email}
msgDatabase={this.props.friendlist[i].msgdata}
loadChattingUser={this.props.loadChattingUser}
/>
);
});
return <div>{cardComponent}</div>;
}
}
Here is codesandbox link: https://codesandbox.io/s/chatter-zdljq

setState called everytime I type something in input

so i'm facing an issue where whenever I write something in input, handleCommentAdded is called which calls setState, re-rendering everything. This makes everything that is typed or was typed in the input to appear as comments and i want what is in the input when I click submit to appear as comment. How can I fix this?
class WriteComments extends React.Component {
constructor(props) {
super(props);
this.state = {
commentAdded:"",
}
this.handleButton = this.handleButton.bind(this);
this.handleCommentAdded = this.handleCommentAdded.bind(this);
}
handleCommentAdded(event) {
this.setState({newComment: event.target.value});
}
handleButton() {
return(
<div>
{comment}
</div>
)
}
render() {
return(
<div>
<input type="text" value={this.state.commentAdded} onChange=
{this.handleCommentAdded}/>
<div className="button">
<button
type="button"
onClick={e => this.handleButton(e)}
>
Write
</button>
</div>
)
}
}
Error is calling handleCommentAdded on onChange
set state in handleButton
class WriteComments extends React.Component {
constructor(props) {
super(props);
this.state = {
commentAdded: ""
};
this.inputRef = React.createRef();
this.handleButton = this.handleButton.bind(this);
}
handleButton() {
this.setState({ commentAdded: this.inputRef.current.value });
}
render() {
return (
<div>
<input type="text" ref={this.inputRef} />
<div className="button">
{this.state.commentAdded !== "" ? (
<div>{this.state.commentAdded}</div>
) : (
<button type="button" onClick={e => this.handleButton(e)}>
Write
</button>
)}
</div>
</div>
);
}
}
ReactDOM.render(<WriteComments />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root' />
I created a demo where textfield value can be get by button click. Component will render everytime when setState calls. Hope it can help you!
class App extends React.Component{
state ={ inputValue:"" };
render(){
return(
<div>
<input type="text" value={this.state.inputValue} onChange={this.handleChange} />
<button onClick={this.handleSubmit}>Submit</button>
</div>
);
}
handleChange=(e)=>{
this.setState({ inputValue: e.target.value });
}
handleSubmit=()=>{
console.log("inputValue::", this.state.inputValue);
}
}
ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

How to get data from Form from child component and pass it back to Parent Componet? [duplicate]

This question already has answers here:
How to access a DOM element in React? What is the equilvalent of document.getElementById() in React
(9 answers)
Closed 5 years ago.
I want to add items to the lists.Items come from Child Component's form .
class App extends Component {
constructor(props) {
super(props);
this.state = {
lists: [], // this holds the name of each list
};
}
handleAddList(s) {
this.setState({lists:s});
};
render() {
return (
<div className="App">
<AddList addList={this.handleAddList.bind(this)} />
</div>
);
}
}
What should I write in handleSubmit function such that it return list to parent component?How to access input's value from form element?
class AddList extends Component {
handleSubmit(e) {
e.preventDefault();
this.props.addList(e.target.value); //Isn't this the way to get input from Form ...//
}
render() {
return (
<div id="addListDiv">
<form onSubmit={this.handleSubmit.bind(this)}>
<div id='addList'>
<label>What will be on your next list?
<input type='text' ref='id' id='newID'></input> //How ref is used?????
</label>
</div><br />
<input type='submit' value='Create List' />
</form>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root'));
To access your input value by ref you can use this.refs.id.value and to pass value from child to parent component you can use props.
let {Component} = React;
class App extends Component {
constructor(props) {
super(props);
this.state = {
lists: [], // this holds the name of each list
};
}
handleAddList(s) {
this.setState(prevState => {
return {lists: [s, ...prevState.lists]}
});
};
render() {
return (
<div className="App">
<AddList addList={this.handleAddList.bind(this)} />
{this.state.lists.map((name, i) => <div key={i}>{name}</div>)}
</div>
);
}
}
class AddList extends Component {
handleSubmit(e) {
e.preventDefault();
let name = this.refs.id.value;
if(name) {
this.refs.id.value = '';
this.props.addList(name);
}
}
render() {
return (
<div id="addListDiv">
<form onSubmit={this.handleSubmit.bind(this)}>
<div id='addList'>
<label>What will be on your next list?
<input type='text' ref='id' id='newID'></input>
</label>
</div><br />
<input type='submit' value='Create List' />
</form>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Using fetch in reactjs component reinitialize application (state)

After pushing submit button I use fetch button to get information about git user from git api. After information is fetched I write it to database and then setState with userIsFetched: true and then conditionally render components.
The problem is that after I change state userIsFetched: true I see for a second my <Chat /> component, but then I see <Signup /> component. In the console I see that the state is erased. If I use xmlhttprequest then it works fine. Why this is happening?
var database = firebase.database();
/*function readData() {
return firebase.database().ref('users/0dc2074d-f7db-4746-91bd-d6e61498b666').once('value')
.then((data)=>data.val())
}*/
class Chat extends React.Component {
render() {
return (<div>
<div className="row">
<div className="col">header</div>
</div>
<div className="row" >
<div className="col-10">one</div>
<div className="col-2">two</div>
</div>
<div className="row">
<div className="col">footer</div>
</div>
</div>)
}
}
class SignIn extends React.Component {
constructor(props) {
super(props);
this.state = {
signLogin: ''
}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleSubmit() {
this.props.handleSignInSubmit(this.state.signLogin);
}
handleChange(event) {
this.setState({
signLogin: event.target.value
})
}
render() {
return (<div>
<form className="form-signin" onSubmit={this.handleSubmit}>
<h2 className="form-signin-heading">Please sign in</h2>
<br/>
<label className="sr-only">Name</label>
<input type="text" className="form-control" placeholder="Name" required="" autoFocus="" onChange={this.handleChange} value={this.state.value}/>
<br/>
<button className="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div>)
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
}
this.handleSignInSubmit = this.handleSignInSubmit.bind(this);
}
handleSignInSubmit(signLogin) {
fetch(`https://api.github.com/users/${signLogin}`)
.then((response)=>response.json())
.then((user)=>this.writeUserData(uuidv4(), user.name, user.avatar_url))
.then(()=>this.setState({userIsFetched: true}))
.catch( alert );
}
writeUserData(userId, userName, userAvatarUrl) {
firebase.database().ref('users/' + userId)
.set({
userName: userName,
userAvatarUrl : userAvatarUrl
});
}
render() {
console.log(this.state)
return this.state.userIsFetched ? <Chat /> : <SignIn handleSignInSubmit={this.handleSignInSubmit}/>
}
}
ReactDOM.render(<App/>, document.getElementById("root"));
Here is the working example: https://codepen.io/RinatRezyapov/pen/WEEqJW
try enter RinatRezyapov and click Submit.
I've forgotten to add
event.preventDefault();
In SignIn's submit
handleSubmit() {
this.props.handleSignInSubmit(this.state.signLogin);
}
Now it works
handleSubmit(event) {
event.preventDefault();
this.props.handleSignInSubmit(this.state.signLogin);
}

Resources