Props variable is not found - reactjs

I'm learning react native using expo-cli. I'm working on a little exercise to display information about movies after fetching them from API using axios http client. But when I try to pass data from a parent component MoviesList to a child component MovieDetails I get the following screen:
Here is my App component code :
import { View } from 'react-native';
import React, { Component } from 'react';
import Header from './src/components/Header';
import MoviesList from './src/components/MoviesList';
import axios from 'axios';
const API_KEY = "mykey";
class App extends Component {
constructor(props) {
super(props);
this.state = {
movies:[],
movieToSearch:"avengers"
};
}
componentDidMount=async()=>{
const res = await axios.get(`http://www.omdbapi.com/?s=${this.state.movieToSearch}&apikey=${API_KEY}`);
// const data=await res.json();
this.setState({ movies:res.data.Search });
}
render() {
return (
<View style={ { flex:1 } }>
<Header title={"Films"} />
<MoviesList movies={ this.state.movies } />
</View>
);
}
}
export default App;
Code for MoviesList.js:
import React,{ Component } from 'react';
import { View } from 'react-native';
import MovieDetails from './MovieDetails';
class MoviesList extends Component{
renderMovies(){
const { movies } = this.props;
if(movies){
return movies.map(movie => {
return <MovieDetails key={ movie.imdbID } movie = { movie } />
});
}else{
return;
}
}
render(){
return (
<View>
{ this.renderMovies() }
</View>
)
}
}
export default MoviesList;
Code for MovieDetails.js:
import React from 'react';
import { View, Text } from 'react-native';
import Card from './Card';
import CardSection from './CardSection';
import Button from './Button';
const MovieDetails = () =>{
const { Title, Year, Poster } = props.movie;
return (
<Card>
<CardSection>
<Text>{ Title }</Text>
</CardSection>
<CardSection>
<Text>{ Title }</Text>
</CardSection>
<CardSection>
<Button btnLabel="Voir les details" />
</CardSection>
</Card>
)
}
export default MovieDetails;
Everything seems good in my code, and I don't know where the error is coming from.
Here is the github repo so that you can test it locally :https://github.com/jochri3/movieslist

convert
const { Title, Year, Poster } = props.movie;
return (
<Card>
<CardSection>
<Text>{ Title }</Text>
</CardSection>
<CardSection>
<Text>{ Title }</Text>
</CardSection>
<CardSection>
<Button btnLabel="Voir les details" />
</CardSection>
</Card>
)
}
to
const MovieDetails = ({movie}) => ({
<Card>
<CardSection>
<Text>{ movie.Title }</Text>
</CardSection>
...
</Card>
})
and
class MoviesList extends Component{
renderMovies(){
const { movies } = this.props;
if(movies){
return movies.map(movie => {
return <MovieDetails key={ movie.imdbID } movie = { movie } />
});
}else{
return;
}
}
render(){
return (
<View>
{ this.renderMovies() }
</View>
)
}
}
with
class MoviesList extends Component{
constructor(props){
super(props)
}
renderMovies = () => {
const { movies } = this.props;
return movies.map(movie => {
return <MovieDetails key={ movie.imdbID } movie = { movie } />
});
}
render(){
return (
<View>
{ this.renderMovies() }
</View>
)
}
}

Functional components pass props as an argument.
const MovieDetails = () =>{
const { Title, Year, Poster } = props.movie;
return (
<Card>
...
To this:
const MovieDetails = (props) =>{
const { Title, Year, Poster } = props.movie;
return (
<Card>
...

You are using functional component for MovieDetails as follow:
const MovieDetails = () => {
const { Title, Year, Poster } = props.movie;
.......
}
But actual implementation for it is as follow:
const MovieDetails = (props) => {
const { Title, Year, Poster } = props.movie;
......
}
I hope it help you.

const MovieDetails = () =>{
has to be
const MovieDetails = props => {
The component is a function and props are its argument.

Related

Transform a stateless Wrap function to a component with state in react

i would like to create a wrapper component in react, and i need to pass some states to the child components.
The error message i get is:
Failed to compile.
./src/app/layouts/MainLayout.jsx
Line 9: 'children' is not defined no-undef
Line 77: 'Children' is not defined no-undef
Thats the the Wrapper component: MainLayout.jsx
import React, { Component } from 'react'
import { Redirect } from 'react-router'
import { Row, Col, Alert } from 'reactstrap'
import PortfolioTitle from './components/sidemodules/PortfolioTitle';
import AppMenu from './components/menu/AppMenu';
const Api = require('./api/PortfolioApi')
class MainLayout extends Component ({ children }) {
constructor(props) {
super(props)
this.state = {
portfolio: {
id: this.getPortfolioId(props),
},
redirect: null,
errors: []
}
}
getPortfolioId(props) {
try {
return props.match.params.id
} catch (error) {
return null
}
}
componentDidMount() {
if (this.state.portfolio.id) {
Api.getPortfolio(this.state.portfolio.id)
.then(response => {
const [error, data] = response
if (error) {
this.setState({
errors: data
})
} else {
this.setState({
portfolio: data,
errors: []
})
}
})
}
}
render() {
const { redirect, portfolio, errors } = this.state
if (redirect) {
return (
<Redirect to={redirect} />
)
} else {
return (
<>
<Row>
{errors.length > 0 &&
<div>
{errors.map((error, index) =>
<Alert color="danger" key={index}>
{error}
</Alert>
)}
</div>
}
<Col xl={3}>
<PortfolioTitle portfolio={portfolio} />
</Col>
<Col xl={9}>
<AppMenu portfolio={portfolio} />
{/* Here goes the wrapped content */}
{Children}
</Col>
</Row>
</>
)
}
}
}
export default MainLayout
This is the content that will be wrapped.
Smartfolio.jsx
import React from 'react'
import MainLayout from './layouts/MainLayout';
import HistoricalRentability from './components/dashboard/HistoricalRentability'
import PortfolioCompostition from './components/dashboard/PortfolioComposition';
function Smartfolio(props) {
var id = props.portfolio.id;
return (
<>
<MainLayout>
<HistoricalRentability />
<PortfolioCompostition id={id} />
</MainLayout>
</>
)
}
export default Smartfolio
I would like some help to understand how can i get this component working, thanks in advance
Your component should be like this,
class MainLayout extends Component {
......
render() {
const { children } = this.props;
return (
......
{ children }
)
}
}
Refer: https://reactjs.org/docs/components-and-props.html

How Can I Reduce Codes In React Native?

What I'm Trying To Do
My current code is like this.
import React from 'react';
import {
Container, Header, Body, View, Content, Title, Text, Left, Right
} from 'native-base';
import 'react-native-gesture-handler';
import Fire from 'app/src/Fire';
import {
StyleSheet, Image, TouchableOpacity,
} from 'react-native';
export default class All extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
};
}
async componentDidMount() {
const querySnapshot = await Fire.shared.getItems(1);
const items = await Fire.shared.pushItems(querySnapshot);
this.setState({ items });
}
render() {
const { items } = this.state;
return (
<Container>
<View>
{items.map((item) => (
<Image
source={{ uri: item.first_img_url }}
/>
<View>
<Text>{item.name}</Text>
</View>
))}
</View>
</Container>
);
}
}
I have another component that has almost same code as above one.
The differences are class name and
await Fire.shared.getItems(1);
or
await Fire.shared.getItems(2);
I know I should combine the same code into one component.
I would appreciate it if you could give me any advices or tips :)
You can extract this code and pass the number 1 or 2 in props.
import React from 'react';
import {
Container, Header, Body, View, Content, Title, Text, Left, Right
} from 'native-base';
import 'react-native-gesture-handler';
import Fire from 'app/src/Fire';
import {
StyleSheet, Image, TouchableOpacity,
} from 'react-native';
export default class All extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
};
}
async componentDidMount() {
const querySnapshot = await Fire.shared.getItems(this.props.nbrOfItems);
const items = await Fire.shared.pushItems(querySnapshot);
this.setState({ items });
}
render() {
const { items } = this.state;
return (
<Container>
<View>
{items.map((item) => (
<Image
source={{ uri: item.first_img_url }}
/>
<View>
<Text>{item.name}</Text>
</View>
))}
</View>
</Container>
);
}
}
You can call this component in any component like this
<All nbrOfItems={1} />
Or
<All nbrOfItems={2} />

Send value to function in React-Native

I am trying to send value of TextInput to another Class Function in console.log. My approach is when the button is pressed the value FromStr in TextInput will got passed into another class function. Here's my code
import React, { Component } from "react";
import { StyleSheet, Text, View, TextInput, Button } from "react-native";
import receiveMessage from "./receiveMessage"
export default class WeatherProject extends Component{
constructor (props) {
super(props);
this.state={
From:'',
FromStr:'',
}
}
changeText=(From)=>{
this.setState({From})
}
changeText1=(To)=>{
this.setState({To})
}
onPress = ()=>{
this.setState({FromStr: this.state.From})
receiveMessage.receiveMessage();
}
render(){
return (
<View>
<View style={styles.inputFields}>
<TextInput placeholder="From" id="from" style={styles.fromField} onChangeText={this.changeText} />
<View style={styles.buttonStyle}>
<Button
title={"Go Back"}
color="#f194ff"
onPress={this.onPress}
></Button>
</View>
</View>
</View>
);
}
}
receiveMessage.js
import React, { Component } from "react";
export default class receiveMessage extends Component {
static receiveMessage=()=>{
console.log(this.state.FromStr)
}
}
React does not allow to pass the data between react components in this way.
Following is way to pass the data between components in React. To get more insights please follow
import React, { Component } from 'react';
class WeatherProject extends Component {
render() {
const messageToPassed = 'Hello';
return (
<div>
<ReceiveMessage message={messageToPassed} />
</div>
);
}
}
const ReceiveMessage = props => <h1>{props.message}</h1>;
export default App;
here we pass the value from sidemenu component by raising an event
App.js
class App extends React.Component {
handleSubmit = (e, data) => console.log(`my data from props`, data);
render() {
return (
<Sidemenu
onSubmit={(e, data)=>this.handleSubmit(e, data)} />
);
}
}
SideMenu.js
const Sidemenu = props => {
const { onSubmit} = props;
return (
<button onClick={(e, type)=>this.onSubmit(e, 'mydata')} />
);
}

Upload image to redux and show in React-Konva

I have try to upload image to Redux and show in of React-Konva in many ways. But it isn't work. Both in base64 and blob. But in normal situation like using component's state to keep data(base64) it's work. I don't know why.
In my component just have button for upload and React-Konva Component for show image
this is error from base64 store in redux and show to Image Tag
class UploadButton extends Component{
constructor(props){
...
this.handleUpload = this.handleUpload.bind(this);
}
handleUpload({target}){
const reader = new FileReader();
const file = target.files[0];
reader.onloadend = () => {
this.props.dispatch({
type: 'UPLOAD_IMAGE',
image: reader.result,
});
};
reader.readAsDataURL(file);
}
render(){
return(
<div>
<input
value="Upload"
type="button"
onClick={ () => { this.uploadInput.click() } }
/>
<input
id="inputUpload"
ref={ (ref) => { this.uploadInput = ref } }
type="file"
style={ { display: 'none' } }
onChange = { (event) => { this.handleUpload(event) }}
/>
</div>
);
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Stage, Layer, Image } from 'react-konva';
class ShowImage extends Component {
constructor(props){
super(props);
this.props = props;
this.state = {
image : null,
}
}
render(){
return (
<Stage
width={ 500 }
height={ 500 }
>
<Layer>
<Image image={ this.props.image} ></Image>
</Layer>
</Stage>
);
}
}
const mapStateToProps = ( state ) => ({
image : state.image,
});
export default connect(mapStateToProps)(ShowImage);
To use the image in react-konva you have to create a native instance of window.Image.
class VaderImage extends React.Component {
state = {
image: new window.Image()
};
componentDidMount() {
this.state.image.src = this.props.image;
this.state.image.onload = () => {
// need to update layer manually
this.imageNode.getLayer().batchDraw();
};
}
render() {
return (
<Image
image={this.state.image}
y={250}
ref={node => {
this.imageNode = node;
}}
/>
);
}
}
https://konvajs.github.io/docs/react/Images.html

Scroll-View React-Native Not functioning

Parent Component
const App = () => (
<View style={{ flex: 1 }}>
<Header headerText={'Albums'} />
<AlbumList />
</View>
);
Scroll View
import React, { Component } from 'react';
import { ScrollView } from 'react-native';
import axios from 'axios';
import AlbumDetail from './AlbumDetail';
class AlbumList extends Component {
state={ albums: [] };
componentWillMount() {
axios.get('https://rallycoding.herokuapp.com/api/music_albums')
.then(response => this.setState({ albums: response.data }));
}
renderAlbums() {
return this.state.albums.map(album =>
<AlbumDetail key={album.title} album={album} />);
}
render() {
console.log(this.state);
return (
<ScrollView >
{this.renderAlbums()}
</ScrollView>
);
}
}
export default AlbumList;
I am trying to make a ScrollView work. These are the snippet. But still when I run the simulator the scroll view is not working and not giving the full lists of the items.
Try this, basically change the render method return
import React, { Component } from 'react';
import { ScrollView } from 'react-native';
import axios from 'axios';
import AlbumDetail from './AlbumDetail';
class AlbumList extends Component {
this.state={ albums: [] };
componentDidMount() {
axios.get('https://rallycoding.herokuapp.com/api/music_albums')
.then(response => this.setState({ albums: response.data }));
}
renderAlbums() {
return this.state.albums.map(album =>
<AlbumDetail key={album.title} album={album} />);
}
render() {
console.log(this.state);
return (
<div>
<ScrollView></ScrollView>
{this.renderAlbums()}
</div>
);
}
}
export default AlbumList;

Resources