So my App.js is:
import React from 'react';
import './App.css';
import Card from './users/Card';
function App() {
return (
<div className="App">
<Card />
</div>
);
}
export default App;
And the Card.js:
import React, { Component } from "react";
class Card extends Component {
render() {
const people = ["name1", "name2", "name3"];
const peopleList = people.map(person => <p>{person}</p>);
return (
{peopleList}
);
}
}
export default Card;
I'm getting an error:
Objects are not valid as a React child (found: object with keys {peopleList}).
If you meant to render a collection of children, use an array instead.
What am I doing wrong? If I use the map function in the App.js it works fine.
Simply return peopleList;
Demo here
Use a fragment:
return <>{peopleList}</>;
Full code:
class Card extends Component {
render() {
const people = ["name1", "name2", "name3"];
const peopleList = people.map(person => <p>{person}</p>);
return <>{peopleList}</>;
}
}
Demo: CodeSandbox
Related
I am trying to view data using below sample. my list.js file as below:
import React, { Component } from 'react';
import { Person} from './Person';
export class List extends Component {
render() {
const persons = [
{
name:'Frank',
age:30,
city:'city 01'
},
{
name:'Hameed',
age:25,
city:'city 02'
},
{
name:'Jack',
age:24,
city:'city 03'
}
]
const personList = persons.map(person => <Person person={person}/>)
return <div> {personList} </div>
}
}
My person.js file is as below:
import React, { Component } from 'react';
export function Person (person){
return (
<div>
{person.name}
</div>
);
}
I need to print my array value inside the HTML but still did not render the view. I could not fix this.
My App.js file as below:
import logo from './logo.svg';
import './App.css';
import { List} from './components/List'
function App() {
return (
<div className="App">
<List></List>
</div>
);
}
export default App;
You pass the prop person to each <Person />, but inside the <Person /> component you are not getting it well. Each prop you pass, is getting to the function under the props variable, Try this code:
import React, { Component } from 'react';
export function Person (props){
return (
<div>
{props.person.name}
</div>
);
}
Or, alternatively, using destructuring:
import React, { Component } from 'react';
export function Person ({ person }){
return (
<div>
{person.name}
</div>
);
}
In <Person /> component you wrongly used props, try instead as:
export function Person (props) {
const { person } = props
// ... rest
}
See the difference from Person (person) to Person ({ person }). In the explained solution the person is destructured from props.
person.js
import React, { Component } from 'react';
export const Person = (props) => {
return (
<div>
{props.person.name}
</div>
);
}
or,
import React, { Component } from 'react';
export function Person (props){
return (
<div>
{props.person.name}
</div>
);
}
I need help with figuring out why when I use a function component, I do not get a warning of this type:
index.js:1446 Warning: Each child in an array or iterator should have a unique "key" prop.
When I use a class component, this warning pops out.
Thank you in advance for clarification.
function component:
import React from 'react';
import VideoItem from './VideoItem';
const VideoList = ({videos, selectedVideo}) =>{
const renderedItems = videos.map((video) =>{
return <VideoItem key={video.id.videoId} video={video} selectedVideo={selectedVideo}/>
})
return <div>{renderedItems}</div>
}
export default VideoList;
class Component:
import React, { Component } from 'react';
import VideoItem from './VideoItem';
class VideoList extends Component {
render() {
const renderedItems = this.props.videos.map((video) => {
return <div><VideoItem key={video.id.videoId} video={video} selectedVideo={this.props.selectedVideo}/></div>
})
return(
<div>{renderedItems}</div>
)
}
}
export default VideoList;
const renderedItems = this.props.videos.map((video) => {
return <VideoItem key={video.id.videoId} video={video} selectedVideo={this.props.selectedVideo}/>
})
key must be on Div or remove it
In your class component, the key attribute needs to be on the wrapper div element.
In React, in a iteration, each iteration root element should have a key attribute.
In your example, you gave key attribute to VideoItem component. That's the wrapping div who should have it.
import React, { Component } from 'react';
import VideoItem from './VideoItem';
class VideoList extends Component {
render() {
const renderedItems = this.props.videos.map((video) => {
return <div key={video.id.videoId}><VideoItem video={video} selectedVideo={this.props.selectedVideo}/></div>
})
return(
<div>{renderedItems}</div>
)
}
}
export default VideoList;
Maybe your id is not always unique?
Try this (adding idx in map fn)
const renderedItems = this.props.videos.map((video, idx) => {
return <div><VideoItem key={idx} video={video}
selectedVideo={this.props.selectedVideo}/></div>
})
I am really new to Reac.js/Redux.js and javascript in general. I am trying to learn a new language by actually doing it. I am trying to build a simple app that lets you search for the product. Eventually, I will create additional features that will allow a user to add and to remove the items form the list of products.
So far, I have built two containers: ListOfProd and Search. Everything works except I can’t figure out how filter the list of products based on the search criteria entered by a user. Where would be the best place to implement filter? and What would be the best way to filter the array of objects based on the search criteria? Please let me know how I can improve my code!
Container Search.js
import React, {Component} from 'react';
import {bindActionCreator} from 'redux';
import {connect} from 'react-redux';
//import scroll for search
//import Scroll from './components/Search/Scroll';
import SearchBox from '../components/Search/SearchBox';
//import action for search
import {setSearchField} from '../actions/actionSearch';
//list of prod
import ListOfProd from './ListOfProd';
const mapStateToProps = state =>{
return{
product: state.product,
searchField: state.searchField
}
}
const mapDispatchToProps = (dispatch) => {
return{
onSearchChange: (event) => dispatch(setSearchField(event.target.value))
}
}
class Search extends React.Component{
render(){
const {searchField, onSearchChange} = this.props;
// const filterProduct = this.props.product.filter(product =>{
// return product.prod.includes(searchField);
// })
return(
<div className = 'tc'>
<SearchBox searchChange={onSearchChange}></SearchBox>
<ListOfProd></ListOfProd>
</div>
)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Search);
Container ListOfProd.js
// import Component
// hook it up to data store
import React, {Component} from 'react';
import {bindActionCreator} from 'redux';
import {connect} from 'react-redux';
//import Search from 'Search';
class ListOfProd extends React.Component {
createListItems(){
console.log(this.props.product);
return this.props.product.map((product, i) => {
console.log(this.props.product.prod);
console.log(this.props.searchField);
return(
<li key={i}>{product.prod} {product.price}</li>
)
});
}
render(){
return(
<ul>
{this.createListItems()}
</ul>
)
}
}
const mapStateToProps = state =>{
return{
product: state.searchProd.product,
searchField: state.searchProd.searchField
}
}
export default connect(mapStateToProps)(ListOfProd);
Actions
import {CHANGE_SEARCH_FIELD} from '../constants/constants';
export const setSearchField = (text) => ({
type: CHANGE_SEARCH_FIELD,
payload: text
})
Reducer ReducerSearch.js
import {CHANGE_SEARCH_FIELD} from '../constants/constants';
import React from 'react';
const initialState = {
searchField: '',
product : [
{
id: 1,
prod: "prod1",
price: "5"
},
{
id:2,
prod: "prod2",
price: "5"
}
]
}
export const searchProd = (state = initialState, action={}) =>{
console.log(action.payload);
console.log(action.type);
switch(action.type){
case CHANGE_SEARCH_FIELD:{
console.log(action.payload);
console.log(state.product);
return {...state, searchField: action.payload};}
default:
return state;
}
}
App.js
import React, { Component } from 'react';
import SignIn from './components/SignIn/SignIn';
import Register from './components/Register/Register';
import ListOfProd from './containers/ListOfProd';
import Search from './containers/Search';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<Search></Search>
</div>
);
}
}
export default App;
Pleae let me know if you need to see my components.
In general, the best way to implement of filtration is on the key-down event on your text-box.
but before that you have to check your data source and think about your performance, you can set a key limitation or some other limitation.
for your second question, I should say that if your array is in your client use map to have the best performance but you have to get it from a server you can do many things
I'm building a search engine with React.js, where I can look for GIPHY gifs using their API. Everytime I type a word(any word), it always loads the same gifs and when I erase and write another word, the gifs don't update.
index.js:
import React from 'react'; //react library
import ReactDOM from 'react-dom'; //react DOM - to manipulate elements
import './index.css';
import SearchBar from './components/Search';
import GifList from './components/SelectedList';
class Root extends React.Component { //Component that will serve as the parent for the rest of the application.
constructor() {
super();
this.state = {
gifs: []
}
this.handleTermChange = this.handleTermChange.bind(this)
}
handleTermChange(term) {
console.log(term);
let url = 'http://api.giphy.com/v1/gifs/search?q=${term.replace(/\s/g, '+')}&api_key=aOfWv08Of7UqS6nBOzsO36NDvwYzO6io';
fetch(url).
then(response => response.json()).then((gifs) => {
console.log(gifs);
this.setState({
gifs: gifs
});
});
};
render() {
return (
<div>
<SearchBar onTermChange={this.handleTermChange} />
<GifList gifs={this.state.gifs} />
</div>
);
}
}
ReactDOM.render( <Root />, document.getElementById('root'));
search.js
import React, { PropTypes } from 'react'
import './Search.css'
class SearchBar extends React.Component {
onInputChange(term) {
this.props.onTermChange(term);
}
render() {
return (
<div className="search">
<input placeholder="Enter text to search for gifs!" onChange={event => this.onInputChange(event.target.value)} />
</div>
);
}
}
export default SearchBar;
Giflist:
import React from 'react';
import GifItem from './SelectedListItem';
const GifList = (props) => {
console.log(props.gifs);
const gifItems = props.gifs && props.gifs.data && props.gifs.data.map((image) => {
return <GifItem key={image.id} gif={image} />
});
return (
<div className="gif-list">{gifItems}</div>
);
};
export default GifList;
GifItem:
import React from 'react';
const GifItem = (image) => {
return (
<div className="gif-item">
<img src={image.gif.images.downsized.url} />
</div>
)
};
export default GifItem;
I can't seem to find where is the issue here. Is it because of this.handleTermChange = this.handleTermChange.bind(this) and there is no "update" state after?
Any help is welcome :) Thanks!
Its because, you are not putting the term value entered by user in the url, all the time you hit the api with static value term, here:
'http://api.giphy.com/v1/gifs/search?q=${term.replace(/\s/g, '+')}&api_key=aOfWv08Of7UqS6nBOzsO36NDvwYzO6io';
Replace ' by ' (tick), like this:
let url = `http://api.giphy.com/v1/gifs/search?q=${term.replace(/\s/g, '+')}&api_key=aOfWv08Of7UqS6nBOzsO36NDvwYzO6io`;
Check MDN Doc for more details about Template Literals.
I am practicing React native. When I compile the following program, I am getting Cannot read property 'props' of undefined error for Details.js. Kindly let me know as to what went wrong here.
Layout.js
import React, {Component} from 'react';
import Header from './Header';
import Details from './Details';
export default class Layout extends React.Component {
constructor(props){
super(props);
this.state = {
heading: "Welcome no-name guy!",
header: "I am your header",
footer: "I am your footer"
};
}
render() {
return (
<div>
<Header headerprop={this.state.header} />
<Details detailprop={this.state.heading} />
</div>
);
}
}
Details.js
import React from 'react';
const Details = (detailprop) => {
return (
<div className="heading-style">{this.props.detailprop}</div>
);
};
Details.bind(this);
export default Details;
Header.js
import React, {Component} from 'react';
export default class Header extends React.Component {
render(){
return(
<div>{this.props.headerprop}</div>
);
}
}
In functional components, the props are passed as the first parameter. So, you only need to do this:
const Details = (props) => {
return (
<div className="heading-style">{props.detailprop}</div>
);
};
If you know the prop that you want to handle you can destructure that prop:
const Details = ({ detailProp }) => {
return (
<div className="heading-style">{detailprop}</div>
);
};
Your component argument should be props:
const Details = (props) => {
return (
<div className="heading-style">{props.detailprop}</div>
);
};
It could be detailprop as you have (or anything for that matter) but you would then need to access the prop by the confusing call:
detailprop.detailprop
props is the idiomatic approach for React.
Details.js is a stateless functional react component. https://facebook.github.io/react/docs/components-and-props.html
It receives props as its argument. You don't need this here.
import React from 'react';
const Details = (props) => {
return (
<div className="heading-style">{props.detailprop}</div>
);
};
Details.bind(this); // you don't need this
export default Details;
Also, div elements will not work for react-native . Please refer react native docs https://facebook.github.io/react-native/