How to work with objects in an array in another document? - javascript

I need to display the title object from the array in the document App.js.
Everything works when I use an array without any objects :
(before)
App.js:
import React from 'react'
import TodoList from './Todo/TodoList'
function App(props) {
const mass = [
"text1",
"text2",
"text3"
]
return (
<div className='wrapper'>
<TodoList name={mass}> </TodoList>
</div>
)
}
export default App;
But when I add couple objects to array, there is an error (Objects are not valid as a React child (found: object with keys {completed, title}). If you meant to render a collection of children, use an array instead.)
(after)
App.js:
import React from 'react'
import TodoList from './Todo/TodoList'
function App(props) {
const mass = [
{completed: false, title: "text1"},
{completed: false, title: "text2"},
{completed: false, title: "text3"}
]
return (
<div className='wrapper'>
<TodoList name={mass}> </TodoList>
</div>
)
}
export default App;
TodoList.js:
import React from 'react'
import TodoItem from './TodoItem'
const styles = {
ul: {
color: 'red',
margin: 0,
padding: 0,
}
}
export default function TodoList(props) {
return (
<ul style={
styles.ul
}>
<TodoItem name2={props.name}/>
</ul>
)
}
TodoItem.js:
import React from 'react'
import App from '../App'
const styles = {
btn: {
background: 'none',
marginLeft: '30px',
},
divv: {
listStyleType: 'none',
margin:'10px',
marginLeft: '10px',
border:'1px solid #ccc',
padding:'5px',
width: '250px'
}
}
const TodoItem = (props) => {
return (
<div>
{
props.name2.map((comp, momp) =>
{
return (
<div style={styles.divv}>
<li>
<input type="checkbox" /> {momp +1} Test {comp} <button style={styles.btn}>×</button>
</li>
</div>
)
}
)
}
</div>
)
}
export default TodoItem
So in the TodoItem doc I want to work with object named 'title' from array, but not with an array as the whole

try to use comp.title instead of comp in your TodoItem.js file
when you use array with string items in map function you will see only string (items of array)
but when you use object in your array in map function you will see objects as item

Related

React Component doesn't update on updating the state

Map.js
import React, { Component } from "react";
import DatamapsIndia from "react-datamaps-india";
class Map extends Component {
state = { };
render() {
console.log("checkbox value",this.props.checkbox) //correctly updating on clicking on checkbox
return (
this.props.checkbox ?
<DatamapsIndia
regionData={{
Maharashtra: {
value: 10,
},
}}
// hoverComponent={({ value }) => {
// return <span>{value}</span>;
// }}
mapLayout={{
title: "Covid Map",
legendTitle: "Active Cases",
startColor: "#FFDAB9",
endColor: "#FF6347",
hoverTitle: "Count",
noDataColor: "#f5f5f5", // this is the variable that has to change on changing of checkbox value
borderColor: "#8D8D8D",
hoverBorderColor: "#8D8D8D",
hoverColor: "green",
}}
/> :
<DatamapsIndia
regionData={{
Maharashtra: {
value: 10,
},
}}
// hoverComponent={({ value }) => {
// return <span>{value}</span>;
// }}
mapLayout={{
title: "Covid Map",
legendTitle: "Active Cases",
startColor: "#FFDAB9",
endColor: "#FF6347",
hoverTitle: "Count",
noDataColor: "#f24f22", // this is the variable that has to change on changing of checkbox value
borderColor: "#8D8D8D",
hoverBorderColor: "#8D8D8D",
hoverColor: "green",
}}
/>
);
}
}
export default Map;
App.js
import logo from "./logo.svg";
import "./App.css";
import React, { Component } from "react";
import Header from "./Components/Header";
import Body from "./Components/Body";
import Map from "./Components/Map";
class APP extends Component {
state = {
checkbox: false,
};
constructor(props) {
super(props);
this.checkBoxfunction = this.checkBoxfunction.bind(this);
}
checkBoxfunction() {
var check = document.getElementById("customSwitch2").checked;
this.setState(
{
checkbox: check,
},
() => {
console.log(this.state.checkbox);
}
);
}
componentDidMount() {
console.log("CheckBox Updation(APP.JS) Mount", this.state.checkbox);
this.checkBoxfunction();
}
render() {
return (
<div className="App">
<Header
checkbox={this.state.checkbox}
checkBoxfunction={this.checkBoxfunction}
/>
<div className="d-flex flex-column">
<div className="map" style={{ width: "70%" , position:"absolute", right:"10px", top:"130px"}}>
<Map checkbox={this.state.checkbox} />
</div>
<div className="table" style={{ width: "30%"}}>
<Body checkbox={this.state.checkbox} />
</div>
</div>
</div>
);
}
}
export default APP;
Here I'm passing the checkbox value to Map component and I want that whenever the state of the checkbox changes update the "NoDatacolor" value but the thing is not In the way I want .
Even on changing the checkbox state my map "noDataColor" remains the same but the console line in Map component updating the correct value of checkbox each and everytime I'm clicking on it.
It's possible that the <DatamapsIndia {...args} /> handle its props as immutable, I worked with leaflet and faced a similar issue, here you can find information about it.
You can try the following dirty solution:
const { checkbox } = this.props;
...
<DatamapsIndia
...
key={`${checkbox}`}
...
mapLayout={{
...
noDataColor: checkbox ? "#f5f5f5" : "#f24f22",
...
}}
/>
hope this works, please let me know.

How do you display a filtered list based on a state created with use state?

I have some code in codesandbox that is made up of 4 divs, 2 with the category "Book" and 2 with the category "Article". Some buttons at the top should trigger if all the divs should be displayed, only the books, or only the articles. All the buttons show every div currently, so the page doesn't change and it looks like the state stays the same
Here is the code which is on the sandbox
App.js
import React, { useState } from "react";
/* import Container from './design/Container' */
import Test from "./Test";
const posts = [
{
title: "React Hooks",
content: "The greatest thing since sliced bread!",
category: "Book"
},
{
title: "Using React Fragments",
content: "Keeping the DOM tree clean!",
category: "Article"
},
{
title: "Angular Hooks",
content: "The greatest thing since sliced bread!",
category: "Book"
},
{
title: "Angular Fragments",
content: "Keeping the DOM tree clean!",
category: "Article"
}
];
export default function App() {
const [productItems, setProductItems] = useState(posts);
function handleButton(e) {
console.log(e.target.value);
if (e.target.value === "All") {
setProductItems(posts);
} else {
setProductItems(
posts.filter((p, i) => <div key={i}>p.category === e.target.value</div>)
);
}
setProductItems(posts);
console.log(productItems);
}
return (
<div>
<Test posts={productItems} handleButton={handleButton} />
</div>
);
}
Test.js
import React from "react";
function Post({ p,title, content, category }) {
return (
<React.Fragment>
<div>
<h3>{p.title}</h3>
<div>{p.content}</div>
<br />
<i>
in <b>{p.category}</b>
</i>
</div>
</React.Fragment>
);
}
export default function Test({handleButton, posts = [] }) {
return (
<React.Fragment>
<div>
<button value="All" onClick={handleButton}>
All
</button>
<button value="Book" onClick={handleButton}>
Book
</button>
<button value="Article" onClick={handleButton}>
Article
</button>
</div>
<div>
{posts.map((p) => {
return <Post key={p.title} p={p} />;
})}
</div>
</React.Fragment>
);
}
style.scss
.App {
font-family: sans-serif;
text-align: center;
}
You had a few things wrong, one was that you handleButton required an argument but you weren't passing one to it. You need to call it like onClick={(e) => handleButton(e)} another was that you set the state of product items again after your if statement. You had already set it to the filtered value, but then you overwrote it with the unfiltered value like setProductItems(posts); so you have to remove this line. Another was that your filter function didn't really make sense. I would look it up and learn more about it. It takes a function that returns a boolean; it doesn't return a div.
SOLUTION
(sandbox)
App.js
import React, { useState } from "react";
import Test from "./Test";
const posts = [
{
title: "React Hooks",
content: "The greatest thing since sliced bread!",
category: "Book"
},
{
title: "Using React Fragments",
content: "Keeping the DOM tree clean!",
category: "Article"
},
{
title: "Angular Hooks",
content: "The greatest thing since sliced bread!",
category: "Book"
},
{
title: "Angular Fragments",
content: "Keeping the DOM tree clean!",
category: "Article"
}
];
export default function App() {
const [productItems, setProductItems] = useState(posts);
function handleButton(e) {
console.log(e.target.value);
if (e.target.value === "All") {
setProductItems(posts);
} else {
setProductItems(posts.filter((p) => p.category === e.target.value));
}
console.log(productItems);
}
return (
<div>
<Test posts={productItems} handleButton={handleButton} />
</div>
);
}
Test.js
import React from "react";
const Post = ({ pa }) => {
return (
<React.Fragment>
<div>
<h3>{pa.title}</h3>
<div>{pa.content}</div>
<i>
in <b>{pa.category}</b>
</i>
</div>
</React.Fragment>
);
};
export default ({ posts = [], handleButton }) => (
<>
<div>
<button value="All" onClick={(e) => handleButton(e)}>
All
</button>
<button value="Book" onClick={(e) => handleButton(e)}>
Book
</button>
<button value="Article" onClick={(e) => handleButton(e)}>
Article
</button>
</div>
<div>
{posts.map((pa, i) => (
<Post key={i} pa={pa} />
))}
</div>
</>
);

React: Handling mapped states

I'm very new to coding and trying to figure out an issue I have come across.
I am using axios to pull a json file and store it in a state. (I am also using Redux to populate the form)
Then I am using .map() to dissect the array and show one value from within each object in the array.
example json:
unit :
[
{
designName : x,
quantity : 0,
},
{
designName : y,
quantity : 0,
},
{
designName : z,
quantity : 0,
}
]
I have then added an input to select the quantity of the value mapped and now I want to give that value back to the state, in order to send the entire modified json back to the API with Axios.
I feel like I'm close but I'm unsure what I need to do with the handleQuantity function.
Here's my code:
import React, { Component } from 'react';
import store from '../../redux_store'
import axios from 'axios';
import { Button, Card } from 'react-bootstrap'
import { Link } from 'react-router-dom'
store.subscribe(() => {
})
class developmentSummary extends Component {
constructor(props) {
super(props)
this.state = {
prjName: store.getState()[0].developmentName,
units: []
}
}
componentDidMount() {
axios.get('https://API')
.then(
res => {
console.log(res)
this.setState({
units: res.data.buildings
})
console.log(this.state.units.map(i => (
i.designName
)))
}
)
}
handleQuantity() {
}
render() {
return (
<>
<div className="Text2">
{this.state.prjName}
</div>
<div className="Text2small">
Please select the quantity of buildings from the list below
</div>
<ul>
{this.state.units.map((object, i) => (
<div className="Card-center">
<Card key={i} style={{ width: "50%", justifyContent: "center" }}>
<Card.Body>{object.designName}</Card.Body>
<Card.Footer>
<input
className="Number-picker"
type="number"
placeholder="0"
onChange={this.handleQuantity}
/>
</Card.Footer>
</Card>
</div>
))}
</ul>
Thanks in advance!
You have to pass the change event, unit object and the index to handleQuantity and then paste your changed unit as new object in between unchanged units.
Here is the code:
<input
className="Number-picker"
type="number"
placeholder="0"
onChange={(event) => this.handleQuantity(event, object, i)}
/>;
And the code for handleQuantity
handleQuantity = (event, unit, index) => {
const inputedNumber = +event.target.value; // get your value from the event (+ converts string to number)
const changedUnit = { ...unit, quantity: inputedNumber }; // create your changed unit
// place your changedUnit right in between other unchanged elements
this.setState((prevState) => ({
units: [
...prevState.units.slice(0, index),
changedUnit,
...prevState.units.slice(index + 1),
],
}));
}

React - Output an SVG Component Dynamically

Im importing an SVG file as a ReactComponent.
I then want to output this component dynamically based on data from a request.
i.e.
import { ReactComponent as S1 } from '../../assets/images/characteristics/S1.svg';
{characteristics.map(characteristic => (
<div className="characteristic" key={characteristic.key}>
<characteristic.key />
</div>
}
where characteristic.key holds the name of the SVG i.e. "S1" in my example
How can i output the component as this does not work?
Thanks
You can try to do it like this instead:
import { ReactComponent as S1 } from "./path1.svg";
import { ReactComponent as S2 } from "./path2.svg";
// ...
function App() {
// defining characteristics for demonstration purposes
const characteristics = [
{ component: S1, key: "S1" },
{ component: S2, key: "S2" }
];
return (
<div className="App">
{characteristics.map(characteristic => (
<div className="characteristic" key={characteristic.key}>
<characteristic.component />
</div>
))}
</div>
);
}
So the string "S1" would be a good value for a key and you use S1 from the import to actually render the svg component.

React: How to display a default object and highlight li bold?

I am fairly new to React and was wondering if anybody could give me an insight on a problem I am stuck with.
Right now I have a parent(Hello.js) component and two children(Mixer.js and renderCont.js) at the same level.
I am trying to render a list in the Mixer.js and display its corresponding objects in the Hello.js through by passing the values into RenderCont.js. I've gotten to a point where nothing is displayed before I click on any of the list to pass on a object.
From here is where I am stuck: I want the first object of the list to be displayed as a default, at the same time bold the first in the list. And then execute the as I have below.
This is my first time posting a question on stackoverflow so I'm not sure if my question makes sense with the attached codes but I will greatly appreciate any kind of support.
Parent Hello.js:
import React, { Component } from 'react';
import RenderCont from './renderCont.js';
import Mixer from './Mixer';
class Hello extends Component{
constructor(props) {
super(props);
this.state = {
items: [{
id: 0,
name: "First",
background: "white"
}, {
id: 1,
name: "Second",
background: "yellow"
}, {
id: 2,
name: "Third",
background: "blue"
}],
selectedItem: 0
}
this.handle = this.handle.bind(this)
}
handle(value) {
// console.log(this.state.selectedItem);
this.setState({
selectedItem: value
})
}
render() {
const list = this.state.items.map((item) => {
return(item);
})
return (
<div>
<Mixer item={list} onClick={this.handle} selected={this.state.selectedItem}/>
<ul id = "todo" >
<RenderCont item={this.state.selectedItem}/>
</ul>
</div>
)
}
}
export default Hello;
Mixer.js Child1:
import React, { Component } from 'react';
class Mixer extends Component{
constructor(props) {
super(props);
this.state = {
}
this.handleClick = this.handleClick.bind(this);
}
handleClick(item){
this.props.onClick(item);
}
renderTodos(propItems) {
return (
<div>
{propItems.map((item) => (
<li className={this.props.selected === item ? 'media clicked' : 'media'}
key={item.id} onClick = {() => this.handleClick(item)}>
{item.name}
</li>
))}
</div>
)
}
render() {
return (
<div className="yoyoyo">
{this.renderTodos(this.props.item)}
</div>
)
}
}
export default Mixer;
Second Child Comp renderCont.js :
import React, { Component } from 'react';
class RenderCont extends Component{
constructor(props) {
super(props);
}
renderBox(item){
return(
<div style={{color:item.background}}>
{item.id}
{item.name}
</div>
)
}
render() {
return (
<div className="yoyo">
{this.renderBox(this.props.item)}
</div>
)
}
}
export default RenderCont;
and the CSS:
.yoyo{
left: 500px;
background-color:red;
width:500px;
height:500px;
}
.media{
color: black;
}
.clicked{
font-weight: 900;
}
.yoyoyo{
background-color:lightblue;
width:200px;
height:200px;
}
I think the problem is some mismatch between the initial and eventual value of this.props.selected in Mixer.js. You initially set this.state.selectedItem = 0, and this is what is initially passed as the selected prop to Mixer. But the test you apply in that component is
this.props.selected === item ?
While there is one item.id that === 0, there is never an item that === 0. So no items are highlighted at first. But then, once an item is clicked and selectedItem is actually set to an item, the entry is made bold.
So it looks like you need to either make your initial selection equal to the item.id === 0 reference, or consistently refer to items within your components by their id's.

Categories

Resources