Class To Function Component - react-native

I am very new to react native. The app I am developing has functional components.
Is there any way to convert class component to function component or convert this class into a function?
Is it possible to use functional and class component both in single app?
import React from 'react';
import DayPicker, { DateUtils } from 'react-day-picker';
import 'react-day-picker/lib/style.css';
export default class Example extends React.Component {
constructor(props) {
super(props);
this.handleDayClick = this.handleDayClick.bind(this);
this.state = {
selectedDays: [],
};
}
handleDayClick(day, { selected }) {
const { selectedDays } = this.state;
if (selected) {
const selectedIndex = selectedDays.findIndex(selectedDay =>
DateUtils.isSameDay(selectedDay, day)
);
selectedDays.splice(selectedIndex, 1);
} else {
selectedDays.push(day);
}
this.setState({ selectedDays });
}
render() {
return (
<div>
<DayPicker
selectedDays={this.state.selectedDays}
onDayClick={this.handleDayClick}
/>
</div>
);
}
}

Yes you can use both functional and class component in same time
import React, {useState} from "react";
import DayPicker, { DateUtils } from 'react-day-picker';
import 'react-day-picker/lib/style.css';
export default function Example(props = {}) {
// read about useState hooks, it replace state
const [selectedDays, setSelectedDays] = useState([]);
handleDayClick(day, { selected }) {
if (selected) {
const selectedIndex = selectedDays.findIndex(selectedDay =>
DateUtils.isSameDay(selectedDay, day)
);
selectedDays.splice(selectedIndex, 1);
} else {
selectedDays.push(day);
}
setSelectedDays( selectedDays );
}
render() {
return (
<div>
<DayPicker
selectedDays={ selectedDays}
onDayClick={handleDayClick}
/>
</div>
);
}
}

Related

'state' is not defined (no-undef)

I am complete noob and am just following a tutorial in react-native on udemy. However, I have reached a wall and cannot find a solution anywhere?
Currently I am getting an error from ESLint showing that state is undefined.
Here is the complete code:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import axios from 'axios';
class AlbumList extends Component {
state = { albums: [] }; //state is underlined
ComponentWillMount() {
axios.get('https:/rallycoding.herokuapp.com/api/music_albums')
.then(response => this.setState({ albums: response.data }));
}
renderAlbums() {
render() {
console.log(this.state);
return (
<View>
{this.renderAlbums()}
</View>
**strong text**);
}
}
export default AlbumList;
Has there been any update regarding defining 'state' in React-Native?
Sincerely appreciate the help!
Try this out.
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import axios from 'axios';
class AlbumList extends Component {
constructor(props){
super(props);
this.state = {
albums: []
};
this.renderAlbums = this.renderAlbums.bind(this);
}
componentWillMount() {
axios.get('https:/rallycoding.herokuapp.com/api/music_albums')
.then(response => this.setState({ albums: response.data }));
}
renderAlbums() {
return (
<View /> // return your Albums here as you need
);
}
render() {
return (
<View>
{this.renderAlbums()}
</View>
);
}
}
export default AlbumList;

Injecting Store in React component results in Error

I am trying inject a store to my React Component however I am getting the following error:
Undefined is not a function (evaluating 'decorator(target,property,desc)')
In my App.js I have:
import React, { Component } from 'react';
import PoolComponent from './app/Components/PoolComponent';
import MeasurementsStore from './app/Stores/MeasurementsStore';
export default class PoolApp extends Component {
render() {
return (
<PoolComponent store="MeasurementsStore"/>
);
}
}
In my PoolComponent.js
import React, { Component } from 'react';
import { observer, inject } from 'mobx-react';
import { AppRegistry, Text, View, TextInput , Picker, Button} from 'react-native';
#observer
export default class PoolComponent extends Component {
saveItems() {
console.log('Pressed save');
}
render() {
const store = this.props.store;
return (
<View>
<Text>Selecteer Pool</Text>
<Picker>
<Picker.Item label="Big" value="big"/>
<Picker.Item label="Small" value="small"/>
</Picker>
<Text>PH</Text>
<TextInput/>
<Text>Totaal Chloor</Text>
<TextInput/>
<Text>Vrij Chloor</Text>
<TextInput/>
<Button
title="Learn More"
color="#841584"
accessibilityLabel="Opslaan"
onPress={this.saveItems}
/>
</View>
);
}
}
And in MeasurementsStore.js I have
import {observable, action, computed} from 'mobx-react';
export default class MeasurementsStore {
#observable phValue = 0;
#observable freeChlorine = 0;
#observable totalChlorine = 0;
#observable totalAlkalinity = 0;
#action data(data: Object) {
if (data.phValue) {
this.phValue = data.phValue;
}
if (data.freeChlorine) {
this.freeChlorine = data.freeChlorine;
}
if (data.totalChlorine) {
this.totalChlorine = data.totalChlorine;
}
if (data.totalAlkalinity) {
this.totalAlkalinity = data.totalAlkalinity;
}
}
}
You don't need inject in this case. You are passing the store directly to your PoolComponent, so there is no need for it. You need to change a few things however:
Pass the actual store, not just the store name as a string, in App.js:
import React, { Component } from 'react';
import PoolComponent from './app/Components/PoolComponent';
import measurementsStore from './app/Stores/MeasurementsStore';
export default class PoolApp extends Component {
render() {
return (
<PoolComponent store={measurementsStore}/>
);
}
Import from mobx and export an instance of MeasurementsStore in MeasurementsStore.js:
import {observable, action, computed} from 'mobx';
class MeasurementsStore {
#observable phValue = 0;
#observable freeChlorine = 0;
#observable totalChlorine = 0;
#observable totalAlkalinity = 0;
#action data(data: Object) {
if (data.phValue) {
this.phValue = data.phValue;
}
if (data.freeChlorine) {
this.freeChlorine = data.freeChlorine;
}
if (data.totalChlorine) {
this.totalChlorine = data.totalChlorine;
}
if (data.totalAlkalinity) {
this.totalAlkalinity = data.totalAlkalinity;
}
}
}
const measurementsStore = new MeasurementsStore();
export default measurementsStore;

Display Axios-Response [duplicate]

This question already has answers here:
How does connect work without mapDispatchToProps
(2 answers)
Closed 5 years ago.
I want to display the results of may api-call with react. My api returns a JSON Object:
0:{produkt_id: 1, produktname: "Bauernbrot", preis: "4"}
1:{produkt_id: 2, produktname: "Nussbrot", preis: "4.50"}
2:{produkt_id: 3, produktname: "Dinkelbrot", preis: "4.20"}
It works if my react component looks like that:
constructor() {
super();
this.state = {
bread: ' '
};
}
componentDidMount(){
axios
.post('/api/produkte')
.then((res)=> {
console.log(res.data);
this.setState(
{ bread: res.data.produkte[0].produktname }
);
})
.catch((err)=> {})
}
render(){
return (
<div>
<h1>{this.state.bread}</h1>
</div>
);
}
As I am using Redux, i would like to make that request with a redux-action. This action should update my "products" state in my redux store, that i will display in my react component. Unfortunately I can't get that working.
Here is my action:
import axios from 'axios';
import { GET_PRODUCTS } from './types';
export function setProducts(products) {
return {
type: GET_PRODUCTS,
products
};
}
export function updateProducts() {
return (dispatch) => {
return axios
.post('/api/produkte')
.then( res => {
console.log(res);
dispatch(setProducts(res.data.produkte[0].produktname));
})
.catch((err)=> {})
}
}
And my reducer (imported in root reducer):
import {GET_PRODUCTS} from '../actions/types';
const initialState = {
products: {}
};
export default (state=initialState,action = {}) => {
switch(action.type){
case GET_PRODUCTS:
return {
products: action.products
}
default: return state;
}
}
If i call my function "updateProducts()" in Constructor of my react component, I can't see that action being executed in my redux store. :(
import React from 'react';
import { connect } from 'react-redux';
import BestellForm from './BestellForm';
import { updateProducts } from '../../redux/actions/getProducts';
class BestellSeite extends React.Component {
render() {
return (
<BestellForm updateProducts={updateProducts}/>
);
}
}
export default connect (null, { updateProducts })(BestellSeite);
And:
import React, { Component } from 'react';
import './bestellSeite.css';
import moment from 'moment';
import axios from 'axios';
export default class BestellForm extends Component {
constructor() {
super();
this.state = {
bread: ' '
};
}
componentWillMount() {
this.props.updateProducts();
}
}
componentWillMount() {
this.props.dispatch(updateProducts());
}
did the trick

Headless Task use inside component with React Native

I am trying to run a background task using headlessjs in react-native. The problem is that I am unable to access the async task inside the component in order to show it on the view. Here's my default component.
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View,
NativeModules
} from 'react-native';
module.exports = NativeModules.ToastAndroid;
someTask = require('./SomeTaskName.js');
export default class test2 extends Component {
constructor() {
super()
this.state = {
myText: 'My Original Text'
}
}
updateText = () => {
this.setState({myText: 'My Changed Text'});s
}
componentDidMount(){
this.setState({myText: someTask});
someTask.then(function(e){ //<--- error
console.log("lala" + e);
});
}
render() {
return (
<View>
<Text>
abc
</Text>
</View>
);
}
}
AppRegistry.registerComponent('test2', () => test2);
AppRegistry.registerHeadlessTask('SomeTaskName', () => someTask);
As mentioned in the code, I get the error undefined is not a function. I don't know how to make this work. My SomeTaskName.js looks like this.
SomeTaskName.js
module.exports = async (taskData) => {
return taskData.myname;
}
The idea is to simply get the data from the service and show it on the UI.
The solution was to simply move the code inside the componentDidMount function. Here's how I achieved it.
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View,
Image
} from 'react-native';
export default class test2 extends Component {
constructor() {
super()
this.state = {
myText: '1'
}
}
componentWillUnmount() {
}
componentDidMount(){
someTask = async (taskData) => {
this.setState({ myText: taskData.myname});
}
};
}
render() {
return (<Text>Working</Text>);
}
}
AppRegistry.registerHeadlessTask('SomeTaskName', () => someTask);
AppRegistry.registerComponent('test2', () => test2);
You can replace :
someTask = require('./SomeTaskName.js');
by
import SomeTaskName from './SomeTaskName'

React Native Router Flux: passing params between scenes

I have a list of items (jobs) and when an item (job) is being selected, a new scene is being opened. I want the ID of the selected item to be passed from the scene with the list to the other scene with the details about the selected item (job) without using Redux.
Router
import React from 'react';
import { Scene, Router } from 'react-native-router-flux';
import JobsList from './components/JobsList';
import Job from './components/Job';
const RouterComponent = () => {
return (
<Router>
<Scene key="jobs" component={JobsList} initial />
<Scene key="Job" component={Job} title="Test" />
</Router>
);
};
export default RouterComponent;
Jobs list
import React, { Component } from 'react';
export default class JobsList extends Component {
render() {
return (
<TouchableOpacity onPress={() => { Actions.Job({ jobId: jobId }) }}>
...
</TouchableOpacity>
);
}
}
Job
import React, { Component } from 'react';
export default class Job extends Component {
constructor() {
super();
this.state = {
job: {}
};
axios.get(
// PROBLEM: this.props.jobId is empty
`http://api.tidyme.dev:5000/${this.props.jobId}.json`,
{
headers: { Authorization: 'Token token=123' }
}
).then(response => this.setState({
job: response.data
}));
}
render() {
return (
<Text>{this.state.job.customer.firstName}</Text>
);
}
}
You should call super(props) if you want to access this.props inside the constructor.
constructor(props) {
super(props);
console.log(this.props);
}
The best practice is defining Components as pure functions:
const Job = ({ job, JobId}) => {
return (
<Text>{job.customer.firstName}</Text>
);
}
otherFunctions() {
...
}