React-Native | Problem with setState can't be read - javascript

The setState can't be read, the value of print1 stays 0000 it must be changed to array[0].date and the alert shows the value of array[0].date
the problem is that it works before.
PS: there's no error shown
export default class WebServiceUse extends Component {
constructor(props) {
super(props);
this.state = ({
print1: '0000',
})
}
componentDidMount() {
fetch('https://**********', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ id: '1' })
}).then((response) => response.json()).then((responseJson) => {
let array = responseJson.ed5aaf3d933385698d872d0a0d5d4f36
alert(array[0].date)
this.setState = ({
print1: array[0].date,
})
})
.catch((error) => {
console.error(error)
});
}
render() {
return (
<View style={styles.container}>
<Text>Test:</Text>
<Text>{this.state.print1}</Text>
</View>
);
}
}

When you set the state in the constructor, this.state = is assigning the initial value of the state object so it's not really a function. Further down the lifecycle calling this.setState IS a function that merges existing state with your changes. So change
this.state = ({
print1: '0000',
})
to
this.state = {
print1: '0000'
}
Also you're not assigning state, you're calling the function so don't use =
this.setState = ({
print1: array[0].date,
})
ought to be
this.setState({
print1: array[0].date
})

Try doing this
export default class WebServiceUse extends Component {
constructor(props) {
super(props);
this.state = ({
print1: '0000',
})
}
componentDidMount() {
var that = this;
fetch('https://**********', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ id: '1' })
}).then((response) => response.json()).then((responseJson) => {
let array = responseJson.ed5aaf3d933385698d872d0a0d5d4f36
alert(array[0].date)
that.setState({
print1: array[0].date,
})
})
.catch((error) => {
console.error(error)
});
}
render() {
return (
<View style={styles.container}>
<Text>Test:</Text>
<Text>{this.state.print1}</Text>
</View>
);
}
}

Related

Reac js TypeError: this.state.data.map is not a function

class CardList extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
};
}
componentDidMount() {
firestore
.collection('users')
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
this.setState({ data: doc.data() });
});
});
}
render() {
return (
<div className="cardlist">
{this.state.data.email
? this.state.data.map((data) => {
return <div>{this.state.data.email}</div>;
})
: console.log('error')}
</div>
);
}
}
TypeError: this.state.data.map is not a function
I want to take out the emails in the Firestore and print them out, but I can't print them because of typeerror. Why is there an error?
console.log(this.state.data) result is
{ createdAt: t, name: 'good', email: 'good#gmail.com', isTutor: 'off' };
{ name: 'joe', isTutor: 'on', email: 'joe#gmail.com', createdAt: t };
You are not assigning value to your array properly, rather you should do like the code below. I've also refactored the code in render function.
class CardList extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
};
}
componentDidMount() {
firestore
.collection('users')
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
this.setState({ data: [...this.state.data, doc.data()] });
});
});
}
render() {
return (
<div className="cardlist">
{this.state.data &&
this.state.data.map((item) => {
return <div>{item.email}</div>;
})}
</div>
);
}
}
this.setState({ data: doc.data() }); - you are not adding to the state, but replacing it with an object for each doc. And you cannot .map an object, thus the error.

Pass props to another component and redraw the page

In 1 component, when I click on the picture, I get its id, which I pass to another component via props. I need to receive these props every time and send a feth - request with the id of the image and then redraw the component. How to do it correctly?
first component
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
isOpen: false,
images: [],
idImg: ''
};
}
openModal = (e) => {
this.setState({ isOpen: true, idImg: e.target.id });
}
render() {
const {error, isLoaded, images} = this.state;
if (error) {
return <p>Error</p>
} else if (!isLoaded) {
return <p> Loading ... </p>
} else {
return (
<div className="row align-items-center m-4" onChange={this.onSelect}>
<Modal
isOpen={this.state.isOpen}
onCancel={this.handleCancel}
onSubmit={this.handleSubmit}
idImg={this.state.idImg}
></Modal>
{images.map(item => (
<div key={item.image_id} className="col-lg-4 col-lg-4 sm-1 p-2" style={{Style}} >
<img id={item.image_id} src={item.src} alt={item.src} onClick={this.openModal}></img>
</div>
))}
</div>
)
}
}
2 component:
export default class Modal extends Component {
constructor(props){
super(props);
this.state = {
imgSrc: ' ',
commentList: [],
_id: this.props.idImg
}
}
componentDidMount(){
fetch(`./api/${this.state._id}`, {
method: 'GET',
})
.then(res => res.json())
.then((result) => {
this.setState({
isLoaded: true,
imgSrc: result.src
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
);
Factor out the fetch into a utility function that can be called in componentDidMount and componentDidUpdate when the props update.
Also, don't store passed props into local component state, this is an anti-pattern in react. You can simply consume the passed idImg prop in the lifecycle methods.
export default class Modal extends Component {
constructor(props){
super(props);
this.state = {
imgSrc: ' ',
commentList: [],
}
}
fetchImage = imageId => {
this.setState({ isLoaded: false }); // <-- set loading state
fetch(`./api/${imageId}`, {
method: 'GET',
})
.then(res => res.json())
.then((result) => {
this.setState({
isLoaded: true,
imgSrc: result.src
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
);
};
componentDidMount() {
this.fetchImage(this.props.idImg); // <-- pass idImg prop
}
componentDidUpdate(prevProps) {
if (prevProps.idImg !== this.props.idImg) { // <-- compare idImg values
this.fetchImage(this.props.idImg); // <-- pass idImg prop
}
}
export default class Modal extends Component {
constructor(props){
super(props);
this.state = {
imgSrc: ' ',
commentList: [],
_id: this.props.idImg
}
this.nameFunction=this.nameFunction.bind(this);
}
componentDidMount(){
this.nameFunction();
}
componentDidUpdate(prevProps) {
if (prevProps.idImg!== this.props.idImg) {
this.setState({
_id: this.props.idImg,
})
}
}
nameFunction(){
fetch(`./api/${this.state._id}`, {
method: 'GET',
})
.then(res => res.json())
.then((result) => {
this.setState({
isLoaded: true,
imgSrc: result.src
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
);
}

map is not a function in react

I've been trying for three days to solve that I can not put several elements in an array,but if I can put only one When I put in the return this.state.dat.nombre or dat.carrera it works, but if I try to put with the map function I do not get
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
dat: [],
isFetch: true
};
}
componentDidMount() {
var url =
"https://cors-anywhere.herokuapp.com/http://sipla.cuci.udg.mx/sc/horariop.php?c=219359735&k=0d8ce4fab5f4df9ce711cae81e044e1a";
fetch(url, {
method: "GET",
headers: {
"X-Requested-With": "XMLHttpRequest"
}
})
.then(response => {
return response.json();
})
.then(art => {
this.setState({ dat: art, isFetch: false });
});
}
render() {
if (this.state.isFetch) {
return "cargando....";
}
this.state.dat.map(art => {
return (
<tr key={art.codigo}>
<td>{art.nombre}</td>
<td>{art.carrera}</td>
<td>{art.horarios}</td>
</tr>
);
});
}
}
export default App;
When I checked your API, I got this data
{
carrera: "INGENIERIA EN COMPUTACION"
ciclo_ingreso: "2019A"
clave_carrera: "INCO"
codigo: "219359735"
cu: "CENTRO UNIVERSITARIO DE LA CIENEGA"
estatus: "ACTIVO"
fecha_consulta: "2019-07-12 12:20:20"
horarios: (4) [{…}, {…}, {…}, {…}]
nivel: "LICENCIATURA"
nombre: "MARIA CECILIA PEREZ PEREZ"
sede: "CAMPUS OCOTLAN"
ultimo_ciclo: "2019B"
}
This is not array. map function for array.
If you want to use this data, you can just write like this.
render() {
if(this.state.isFetch){
return 'cargando....'
}
const {dat} = this.state;
return (
<tr key={dat.codigo}>
<td>{dat.nombre}</td>
<td>{dat.carrera}</td>
<td>{dat.horarios}</td>
</tr>
);
}
Just copy this code and run, you will get desired answer
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
dat: [],
isFetch: true
};
}
componentDidMount() {
let dat = []
var url =
"https://cors-anywhere.herokuapp.com/http://sipla.cuci.udg.mx/sc/horariop.php?c=219359735&k=0d8ce4fab5f4df9ce711cae81e044e1a";
fetch(url, {
method: "GET",
headers: {
"X-Requested-With": "XMLHttpRequest"
}
})
.then(response => {
return response.json();
})
.then(art => {
dat.push(art)
this.setState({ dat, isFetch: false });
});
}
render() {
if (this.state.isFetch) {
return "cargando....";
}
this.state.dat.map(art => {
return (
<tr key={art.codigo}>
<td>{art.nombre}</td>
<td>{art.carrera}</td>
<td>{art.horarios}</td>
</tr>
);
});
}
}
export default App;```

ReactJS & Redux access state "constructor" from another file

I'm just trying to post a data everything working fine if I put the fetch function in the same file but when I moved it to another file it shows cannot read property, I've tried this.props instead of this.state, how can I connect this file to constructor()
scr/component/layout.js
import React, {Component} from 'react';
import { connect } from 'react-redux';
import {bindActionCreators} from 'redux';
import { fetchUsers, postUsers } from '../actions/usersAction';
class Layout extends Component {
constructor(){
super()
this.state = {
name: '',
age: ''}
}
onUserUpdate(filed, event){
console.log('onUserUpdate: ' + filed + '==' + event.target.value);
if (filed == 'name') {
this.setState({
name: event.target.value
})
return
}
if (filed == 'age') {
this.setState({
age: event.target.value
})
return
}
}
componentDidMount() {
this.props.fetchUsers();
}
render() {
const { act } = this.props;
const fetchUserss = act.users.map(d => <tr key={d.id}><td>{d.name}</td><td>{d.age}</td></tr>);
return (
<div className="App">
<label>
name:
</label>
<input type="text" name="name" onChange={this.onUserUpdate.bind(this, 'name')} placeholder="Enter Name"/>
<label>
age:
</label>
<input type="text" name="age" onChange={this.onUserUpdate.bind(this, 'age')} placeholder="enter username"/>
<button type="simpleQuery" onClick={this.props.postUsers.bind(this)}>Add News</button>
<table>
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
{fetchUserss}
</tbody>
</table>
</div>
);
}
}
function mapStateToProps(state) {
return {
act: state.users,
};
}
function matchDispatchToProps(dispatch) {
return bindActionCreators({fetchUsers, postUsers}, dispatch)
}
export default connect(mapStateToProps, matchDispatchToProps)(Layout);
src/actions/userAction.js
export const fetchUsers = (data) =>{
return{
type: "USERS",
payload: fetch('http://rest.learncode.academy/api/johnbob/friends',{
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => res.json())
}
};
export const postUsers = (event) =>{
let users = {
name: this.state.name,
age: this.state.age
}
return{
type: "USERS_POST",
payload: fetch('http://rest.learncode.academy/api/johnbob/friends',{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(users),
})
.then(res => res.json())
}
};
src/reducers/userReducer.js
const initalState = {
fetching: false,
fetched: false,
users: [],
error: null
};
export default function(state=initalState, action) {
let newState = Object.assign({}, state);
switch(action.type){
case "USERS_PENDING":{
return {...state, fetching: true,loading: false,}
}
case "USERS_FULFILLED":{
return {...state, fetching:false, fetched: true, users: action.payload,}
}
case "USERS_REJECTED":{
return {...state, fetching: false, error: action.payload,}
}
case "USERS_POST_PENDING":{
return {...state, fetching: true,}
}
case "USERS_POST_FULFILLED":{
return newState;
}
case "USERS_POST_REJECTED":{
return {...state, fetching: false, error: action.payload,}
}
default:
return state;
}
}
Please let me know if I miss out any information.
If this has already been asked, I would greatly appreciate if you are able to point me in the right direction.
Thank you so much!
You need to pass that data to your postUsers() function.
<button
type="simpleQuery"
onClick={() => this.props.postUsers(this.state.name,this.state.age)}
>Add News</button>
Then in your postUsers() function should take in those parameters:
export const postUsers = (name, age) => ({
type: "USERS_POST",
payload: fetch('http://rest.learncode.academy/api/johnbob/friends',{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name,
age,
}),
})
.then(res => res.json())
});
We cannot access state outside of a component. You can pass the state variables are params to the postUsers function.
<button type="simpleQuery" onClick={this.props.postUsers(this.state.name,this.state.age)}>Add News</button>
And in your postUsers function
export const postUsers = (name,age) =>{
let users = {
name: name,
age: age
}
return{
type: "USERS_POST",
payload: fetch('http://rest.learncode.academy/api/johnbob/friends',{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(users),
})
.then(res => res.json())
}
};
I can see that you have tried to bind a scope to an arrow function. You cannot do that. Arrow functions do not have a scope.
Instead, you should write a normal function.
either,
let postUsers = function() {};
or
function postUsers(){}
In other words this inside an arrow function is always inherited from the parent function. So in your case, this is not undefined, but it is not the this you expect.

Issue with react state not updating/incrementing

I'm trying to do pagination by clicking on some text that calls a method to increment the state value. The state value then gets passed to the axios call which should then call the next page. I'm noticing however that while the state is getting increment in a console.log from the render function, the axios call is not getting called again with the new state value. Anyone have any idea how I can fix this?
constructor(props) {
super(props);
this.state = {
people: [],
planets: [],
page: 1
};
this.pageIncrementer = this.pageIncrementer.bind(this);
}
componentWillMount() {
let page = this.state.page;
axios({
method: 'GET',
url: `http://localhost:3008/people?_page=${page}&_limit=10`
}).then((response) => {
this.setState({
people: response
});
}).catch((error) => {
console.log('There is an error in the Card axios call for people: ', error);
})
axios({
method: 'GET',
url: `http://localhost:3008/planets?_page=${page}&_limit=10`
}).then((response) => {
this.setState({
planets: response
});
}).catch((error) => {
console.log('There is an error in the Card axios call for planets: ', error);
})
}
pageIncrementer() {
this.setState({
page: this.state.page + 1
});
}
componentWillMount called only once, you need componentDidUpdate
https://facebook.github.io/react/docs/react-component.html#componentdidupdate
let getData = () => Math.random();
class Example extends React.Component{
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this)
this.state = {
name: ''
};
}
componentWillMount(){
console.log('componentWillMount')
}
componentDidUpdate(){
console.log('componentDidUpdate')
}
handleChange(e) {
this.setState({
name: this.props.getData()
});
}
render() {
return <div className="widget">
{this.state.name}
<button onClick={this.handleChange}>Inc</button>
</div>;
}
}
React.render(<Example getData={getData}/>, document.getElementById('container'));
Edit(alternative way):
let getData = () => Math.random();
class Example extends React.Component{
constructor(props) {
super(props);
this.makeRequest = this.makeRequest.bind(this)
this.state = {
page:1,
name:''
};
}
makeRequest(next){
fetch('https://jsonplaceholder.typicode.com/posts/'+this.state.page)
.then(
result => {
console.log('do')
return result.json()}
)
.then(
(resp) => this.setState({
name:resp, page:this.state.page+1})
)
}
render() {
return <div className="widget">
{this.state.name}
<button onClick={this.makeRequest}>Request</button>
</div>;
}
}
React.render(<Example getData={getData}/>, document.getElementById('container'));

Categories

Resources