I have an array of names and I need to loop through the index and print the names in render
const names = ['John','Sara','Michael','Timothy']`
render: (props) => ({
<div>
props=names[];
</div>
});
You yan use for ... in loop to iterate through indexes.
const names = ['John','Sara','Michael','Timothy'];
for(const index in names) {
console.log(`${index} of ${names[index]}`);
}
const names = ["John", "Sara", "Michael", "Timothy"];
class Content extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
<h1>Names</h1>
{this.props.names ? (
this.props.names.map((name, index) => (
<p key={name + index}>{name}</p>
))
) : (
<p>No names found</p>
)}
</div>
);
}
}
ReactDOM.render(<Content names={names} />, document.getElementById("app"));
<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="app"> </div>
You have to improve the part of your code. It doesn't seem like a JSX part. Here, how I suppose it can be:
render() {
const names = ['John','Sara','Michael','Timothy'];
return <div>
{names.map((item, index) => (
<div key={index}>
{item}
</div>
))}
</div>;
}
You can use map() to accomplish your demand.
render() {
const names = ['John','Sara','Michael','Timothy'];
return (
<div>
{ names.map((name, index) => <div key={index}>{ name }</div> }
</div>
);
}
Related
I'm using sortable drag and drop which works fine. The problem is that I'd like users to be able to remove items. The SortableItem component isn't accessible as it came with the code, so I can't pass an event handler that takes index as an argument. Here's what I have so far:
const SortableItem = SortableElement(
({value}) =>
<ul>{value}</ul>
);
const SortableList = SortableContainer(({items}) => {
return (
<ul>
{items.map((value, index) => (
<SortableItem key={`item-${index}`} index={index} value={value} />
))}
</ul>
);
});
export class BlocksContainer extends React.Component {
constructor(props){
super(props);
this.state = {
items: [],
};
}
onSortEnd = ({oldIndex, newIndex}) => {
this.setState({
items: arrayMove(this.state.items, oldIndex, newIndex),
});
};
addBlock = (block) =>{
let arr = [...this.state.items, block];
this.setState({items: arr})
}
removeBlock = (index) => {
let remove = [...this.state.items];
remove.filter(block => block === index);
this.setState({items:remove})
}
render() {
return (<div><div onChange={console.log(this.state)} className="sortableContainer"><SortableList items={this.state.items} onSortEnd={this.onSortEnd} /></div>
<h2>Blocks</h2>
<button onClick={() => this.addBlock(<BannerImage remove={this.removeBlock} />)}>Banner Image</button>
<button onClick={() => this.addBlock(<ShortTextCentred remove={this.removeBlock}/>)}>Short Text Centred</button>
<h2>Layouts</h2>
<hello />
</div>
)
}
}
Since you dont have control over the events of the SortableItem component, you can wrap that component in a component you do have control over.
For example, if i wanted to add a click handler to the SortableItem, i would add it instead to the div wrapper:
const SortableList = SortableContainer(({ items }) => {
return (
<ul>
{items.map((value, index) => (
<div onClick={this.someEventHandler}>
<SortableItem key={`item-${index}`} index={index} value={value} />
</div>
))}
</ul>
);
});
I have a search page, which queries an api to get an array of objects. It then renders a for each element of the array. I'm trying to achieve this like so:
export default class SearchScreen extends Component {
constructor(props) {
super(props);
this.state = {
results: null
};
}
componentDidMount() {
const apiUrl =
"foo";
fetch(apiUrl)
.then(response => response.json())
.then(response =>
this.setState({
results: response.results
})
);
}
render() {
{this.state.results ? (
const items = this.state.results.map((item, index) => {
return (
<div>
<SearchResult name={item.name} />
</div>
);
})
return <div>{items}</div>;
) : (<div> LOADING...</div>)}
}
So, if this.state.results is not null, it should map its contents to a const, and then generate SearchResult elements.
It is complaining that const is an unexpected keyword. Is there something wrong with conditionally defining constants?
The syntax is incorrect, below is fixed one:
render() {
const items = this.state.results ? (
this.state.results.map((item, index) => {
return (
// Use better key
<div key={index}><SearchResult name={item.name} /></div>
);
}
)) : 'LOADING...';
return <div>{items}</div>;
}
Statements (like const items = [];) cannot be used with the ternary operator. You can only use expressions. If you want to write a full statement, you have to use if.
You can change the logic a bit to accomplish what you want with the ternary operator though:
return this.state.results ? (
<div>
{this.state.results.map((item, index) => (
<div>
<SearchResult name={item.name} />
</div>
))}
</div>
) :
(
<div> LOADING...</div>
);
Try to fix like this:
render() {
return (
<div>
{this.state.results
? this.state.results.map((item, index) => <SearchResult name={item.name} />)
: 'LOADING...'}
</div>
);
}
I have this code for pagination and search:
return this.props.todos.filter( (todo) => todo.text.toLowerCase().indexOf(this.state.searchText.toLowerCase()) !== -1 ).slice( (currentPage - 1) * pageSize, currentPage * pageSize ).map((todo,todoIndex) => {
return <Todo
key={todo.id}
{...todo} // pass all the todo property
onClick={() => onTodoClick(todo.id)}
onTrashClick={() => onDeleteClick(todo.id, todoIndex)}
handleSelectedTodo = {this._handleSelectedTodo}
isChecked={this.state.checkedIds.includes(todo.id)}
/>
On the Todo component I am thinking of pushing tag inside the text that matches the searchText state. Something Like this:
todo.text.indexOf(this.state.searchText) ? todo.text.split(').push('<b>.....
So if some part of the text matches the searchText state, I will push tag so the result would be like this when this.state.searchText = 'cde' and text = 'abcdefg':
'a<b>cde</b>fg'
Help?
Maybe something like this ?
const Todo = ({ rSearch, text }) => {
var strs = text.split(rSearch);
return (
<span>
{strs.map(
(str, i) =>
rSearch.test(str) ? <b key={i}>{str}</b> : <span key={i}>{str}</span>
)}
</span>
);
};
class TodoList extends React.Component {
state = {
searchText: 'cde'
};
render() {
const { items } = this.props;
const { searchText } = this.state;
const rSearch = new RegExp(`(${searchText})`, 'g');
return (
<div>
<input type="text" defaultValue={searchText} />
<ul>
{items.map((item, i) =>
<li key={i}>
<Todo rSearch={rSearch} text={item.text} />
</li>
)}
</ul>
</div>
);
}
}
const todoItems = [
{
text: 'abcdefgh'
},
{
text: 'ijkcdefgh'
}
];
ReactDOM.render(
<TodoList items={todoItems} />,
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>
I have following code:
export class Highlights extends React.Component {
render() {
return (
<div>
{JSON.stringify(this.props.highlights_data.data)}
</div>
)
}
}
This prints out the following:
{"active":{"label":"Active","value":"12"},"automatic":{"label":"Automatic","value":"8"},"waiting":{"label":"Waiting","value":"1"},"manual":{"label":"Manual","value":"3"}}
How can I iterate over the highlights_data.data props to call another Component passing down label and value ?
Except for #Dan's answer, I don't believe the other answers are any helpful/useful to you as they don't iterate through your JSON object.
To do this properly, you would need to iterate through each of your keys in your JSON object. There are a few ways you can do this, one of which is with Object.keys(). Like the code snippet below.
This solution iterates through each key in your JSON object and pushes it into an array. Once you have that array, you can iterate through it with map(), as you would normally, and pass your relevant props down to another child component.:
class MyApp extends React.Component {
render() {
var json = {"active":{"label":"Active","value":"12"},"automatic":{"label":"Automatic","value":"8"},"waiting":{"label":"Waiting","value":"1"},"manual":{"label":"Manual","value":"3"}};
var arr = [];
Object.keys(json).forEach(function(key) {
arr.push(json[key]);
});
return <ul>{arr.map(item => <MyAppChild key={item.label} label={item.label} value={item.value} />)}</ul>;
}
}
class MyAppChild extends React.Component {
render() {
return <li>{this.props.label + " - " + this.props.value}</li>;
}
}
ReactDOM.render(<MyApp />, document.getElementById('myapp'));
<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="myapp"></div>
export class Highlights extends React.Component {
render() {
const { data } = this.props.highlights_data;
return (
<div>
{
Object.keys(data).map((e, i) => {
<SomeComponent key={i} {...e} />
})
}
</div>
)
}
}
<div>
{this.props.highlights_data.data.map((e, i) =>
<SomeComponent key={i} label={e.label} value={e.value} />
)}
</div>
You could just send in the item itself.
<SomeComponent key={i} item={e} />
And access label and value in the child with props.item.label or props.item.value.
//let myJSON={"attr1":"abcdef", "attr2":"12345", "attr3":"hello"};
<p>
{Object.keys(myJSON).map((innerAttr, index) => {
return (
<span key={index}> {innerAttr}: {myJSON[innerAttr]}<br/></span>
)})
}
</p>
var Highlight = React.createClass({
render: function() {
const {value, label} = this.props;
return <div>{label}: {value}</div>;
}
});
var Highlights = React.createClass({
render: function() {
const {active, automatic, waiting, manual} = this.props.highlights_data.data;
return (
<div>
<Highlight {...active} />
<Highlight {...automatic} />
<Highlight {...waiting} />
<Highlight {...manual} />
</div>
);
}
});
const data = {data:{"active":{"label":"Active","value":"12"},"automatic":{"label":"Automatic","value":"8"},"waiting":{"label":"Waiting","value":"1"},"manual":{"label":"Manual","value":"3"}}};
ReactDOM.render(
<Highlights highlights_data={data} />,
document.getElementById('container')
);
I have the following array:
const elements = [
{
title: "foo"
section: <div>Foo <button onClick={sayHello}>Greet</button></div>
},
{
title: "bar"
section: <div>Bar <button onClick={sayHello}>Greet</button></div>
}
];
I want to render the component with something like:
const someSections = this.state.elements.map((item, i) => (
<div key={i}>
{item.section}
</div>
));
...
render(){
return (
...
<div>
{someSections}
</div>
)
}
But I can't render them. The error is:
Uncaught Error: objects are not valid as a React child
Check the working solution:
const data = [
{
title: "foo",
section: <div>Foo <button>Greet</button></div>
},
{
title: "bar",
section: <div>Bar <button>Greet</button></div>
}
]
class App extends React.Component{
render(){
return(
<div>
{
data.map((item,i)=>{
return <div key={i}>{item.section}</div>
})
}
</div>
)
}
}
ReactDOM.render(
<App/>,
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'></div>
normally you would do something like this.
render(){
let someSections = this.state.elements.map((item, i) => (
<div key={i}>
{item.section}
</div>
));
return (
<div>
{someSections}
</div>
)
}