stuck at Displaying Updated Array Data - reactjs

I have an array List and I'm using the .push() method to add new elements to it and then concat the input with List in Onclickadd method but its not updating the array to display the items in to-do
import React from 'react'
import './App.css'
class App extends React.Component {
constructor(){
super()
this.state={
List: ['potato']
}
}
onAddChange=(event)=>{
this.setState=({
input: event.target.value
})
}
Onclickadd=()=>{
console.log('clicked')
this.setState=({List: this.state.List.concat(this.state.input)})
}
render (){
return (
<div className="App">
<h1>TODO LIST</h1>
<input onChange={this.onAddChange} type='text' placeholder='Add Items'/>
<button onClick={this.Onclickadd} className='btn'>Add</button>
<ol>
{this.state.List.map((items, keys) => {
return <li key={keys}> {items}</li>
})}
</ol>
</div>
);
}
}
export default App;

this.setState is an function witch expects an object, you are trying to assign the value, instead off this.setState= use;
this.setState({
input: event.target.value
})
class App extends React.Component {
constructor(){
super()
this.state={
List: ['potato']
}
}
onAddChange=(event)=>{
this.setState({
input: event.target.value
})
}
Onclickadd=()=>{
this.setState({List: this.state.List.concat(this.state.input)})
}
render (){
return (
<div className="App">
<h1>TODO LIST</h1>
<input onChange={this.onAddChange} type='text' placeholder='Add Items'/>
<button onClick={this.Onclickadd} className='btn'>Add</button>
<ol>
{this.state.List.map((items, keys) => {
return <li key={keys}> {items}</li>
})}
</ol>
</div>
);
}
}
ReactDOM.render(<App />, document.body);
<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>
More info about setState can be found here

this.setState=... is the issue in your code. It is a function call there is no assignment using =.
You have done the same mistake in two places
Change the onAddChange to
onAddChange=(event)=>{
this.setState({
input: event.target.value
})
}
and
Onclickadd to
Onclickadd=()=>{
console.log('clicked')
this.setState({List: this.state.List.concat(this.state.input)})
}
Working example => https://codesandbox.io/s/intelligent-galois-ih7w4?file=/src/App.js:294-418

I recommend you to add value={this.state.input} to the input like following :
<input value={this.state.input} onChange={this.onAddChange} type='text' placeholder='Add Items'/>
The syntax of this.setState() is not right, it's like this :
this.setState({ List: this.state.List.concat(this.state.input) })
this.setState({ input: event.target.value })

Related

How to add a new component with each input?

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>;
}

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()

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 render multiple component in reactjs, what i'm doing wrong?

First i have a function to fetch data from database then
if the data be changed, i will create list components.
but it didnt work, what i'm doing wrong?
console:
class TweetContainer extends React.Component{
constructor(props){
super(props);
this.state = {
tweetData:{},
tweetRender : [],
listTweet:[]
}
}
here is my function to fetch data from database
componentDidMount(){
fetch('http://localhost:5000/tweet')
.then(function(response) {
return response.json();
})
.then(result=>{
this.setState({
tweetData: result
}, ()=>console.log(this.state.tweetData));
});
}
my function to make list component
componentDidUpdate(){
this.state.tweetRender = this.state.tweetData.data.slice(1,6);
console.log(this.state.tweetRender);
this.state.listTweet = this.state.tweetRender.map((tweet)=><Tweet
linkAvatar={'/image/jennyshen.jpg'}
name={"Vuongxuan"}
userName={'#vuggg'}
tweetText={tweet.content} />);
console.log(this.state.listTweet);
}
render(){
return(
<div id="main">
<h2>Tweet</h2>
<div id="stream">
{this.state.listTweet}
</div>
</div>
);
}
}
i dont know what i'm doing wrong.
Accordingly to React docs, componentDidMount lifecycle most common use is for:
Updating the DOM in response to prop or state changes.
And you want to get and render the tweets, right? Not necessarily listen to updates.
For now a solution is remove your componentDidUpdate() method and change your `renderĀ“ method to:
render(){
var tweetRender = this.state.tweetData.data.slice(1,6);
return(
<div id="main">
<h2>Tweet</h2>
<div id="stream">
{listTweet.map((tweet, idx) =>
<Tweet
key={idx}
linkAvatar={'/image/jennyshen.jpg'}
name={"Vuongxuan"}
userName={'#vuggg'}
tweetText={tweet.content} />
)}
</div>
</div>
);
}
It's generally not a good idea to put React elements (JSX) inside your component state. You could instead just store the data in state, and derive the JSX from that data in the render method.
Example
class TweetContainer extends React.Component {
state = {
tweetData: [],
tweetRender: [],
listTweet: []
};
componentDidMount() {
setTimeout(() => {
this.setState({
tweetData: [
{
id: 1,
name: "foo",
username: "#foo"
},
{
id: 2,
name: "bar",
username: "#bar"
}
]
});
}, 1000);
}
render() {
return (
<div id="main">
<h2>Tweet</h2>
<div id="stream">
{this.state.tweetData.map(obj => (
<div key={obj.id}>
{obj.username} - {obj.name}
</div>
))}
</div>
</div>
);
}
}
ReactDOM.render(<TweetContainer />, 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 call specific Object from ObjectArray

Trying to get e.target.data from the objects generated. console.log displays they have props with the data value I assigned them with. How are event specific objects called? I need to access the original value and also want to onClick delete them. But so far everything i tried, only returns _this2 TypeError (is not a function), or data i tried to pass with the onClick handler wasn't passed. this.props.plz_zwischenis a simple array of strings and passed from parent Component.
import React, { Component } from 'react';
export default class checkBox extends Component {
constructor(){
super();
this.state = {
checkboxState: false
};
this.toggle = this.toggle.bind(this);
}
toggle(e){
console.log('toggle was triggered');
}
render(){
let miniBox = this.props.plz_zwischen.map(function(a, index){
return <li key={index} data={a}> <label> {a} </label> <input type="checkbox" onClick={(e) => this.toggle()} /></li>;
});
return(
<div>
<ul id="rowlist">
{miniBox}
</ul>
</div>
);
}
}
When you need to access the another prop in map, it is always a good idea to abstract it to a separate component
function ListItem(props) {
return (
<li>
<label> {props.data} </label>
<input type="checkbox" onClick={(e) => props.toggle(props.data)} />
</li>
);
}
class CheckBox extends React.Component {
constructor(props){
super(props);
this.state = {
checkboxState: false
};
this.toggle = this.toggle.bind(this);
}
toggle(a){
console.log(a);
}
render(){
let miniBox = this.props.plz_zwischen.map((a, index)=>{
return <ListItem key={index} data={a} toggle={this.toggle} />;
});
return(
<div>
<ul id="rowlist">
{miniBox}
</ul>
</div>
);
}
}
ReactDOM.render(<CheckBox plz_zwischen={['a','b','c']}/>, document.getElementById('app'));
<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="app" />
That way you can access the single prop in the child component.
Another way to perform the same thing would be to attach it to the DOM as a custom attribute (since it is a string).
<li data-item={a} key={index} data={a}> <label> {a} </label> <input type="checkbox" onClick={(e) => this.toggle()} /></li>
and then in on click:
event.target.getAttribute('data-item')
Do note that components must begin with capital letters

Resources