Passing data from functional component to app.js - reactjs

I am new to React, still learning the basics of it.
I have a component in students.js:
export const studentslist = () => {
return [
{
name: "aaaa",
surname: "aaa"
},
{
name: "bbbbb",
surname: "bbbb"
},
{
name: "ccccc",
surname: "ccc"
}
];
};
How can I pass this list of students to my App.js into state and use it?

studentslist is not a component as the function only returns an array of data, but it you want to use what the function returns as initial state of a component, you can import it in the component file and assign it to the state either in the constructor or in a class property.
Example
// studentslist.js
export const studentslist = () => {
return [
{
name: "aaaa",
surname: "aaa"
},
{
name: "bbbbb",
surname: "bbbb"
},
{
name: "ccccc",
surname: "ccc"
}
];
};
// App.js
import React from "react";
import studentslist from "./studentslist";
class App extends React.Component {
state = { studentslist: studentslist() };
render() {
return <div>{JSON.stringify(this.state)}</div>;
}
}
const studentslist = () => {
return [
{
name: "aaaa",
surname: "aaa"
},
{
name: "bbbbb",
surname: "bbbb"
},
{
name: "ccccc",
surname: "ccc"
}
];
};
class App extends React.Component {
state = { studentslist: studentslist() };
render() {
return <div>{JSON.stringify(this.state)}</div>;
}
}
ReactDOM.render(<App />, 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>

Related

Changing returned value of mocked hook

I have test in which I am mocking hook which provides data to component. In one test I need to change this data to be an empty array. How can I achieve it? The solution I have clearly doesn't work.
import { fireEvent, render, screen, waitFor } from "#testing-library/react";
import MainPage from "./MainPage";
import withProviders from "../../hoc/withProviders";
let todosMock = [
{ id: "1", name: "abc1", task: "zxc1" },
{ id: "2", name: "abc2", task: "zxc2" },
{ id: "3", name: "abc3", task: "zxc3" },
];
jest.mock("./useDbData", () => ({
__esModule: true,
default: () => todosMock,
}));
const MainPageWithProviders = withProviders(MainPage);
describe("MainPage test", () => {
afterEach(() => {
jest.clearAllMocks();
});
test.each([
{ lang: "fr", text: `Il n'y a pas de Todos à afficher` },
{ lang: "en", text: `There is no todos to display` },
{ lang: "de", text: `Es gibt keine Todos zum Anzeigen` },
])("renders all todos link correctly", ({ lang, text }) => {
//given
todosMock = [];
//when
render(<MainPageWithProviders language={lang} />);
//then
expect(screen.getByText(text)).toBeInTheDocument();
});
});

add dataset dynamically to data list not work

I'm using the react-csv library and I have an issue.
If I dynamically allocate a dataset and download it through CSVLink, then an empty CSV file is downloaded. but if I use static dataset, it just fine
How do I solve it?
Here is my code
import './App.css';
import { CSVLink } from "react-csv";
import { useState } from 'react';
function App() {
const [data, setData] = useState([])
const headers = [
{ label: "gu", key: "region_2depth_name" },
{ label: "legal_dong", key: "region_3depth_name" },
{ label: "address", key: "address_name" },
{ label: "usage", key: "usage"},
{ label: "lat", key: "lat" },
{ label: "lng", key: "lng" }
];
const addData = () => {
data.push({
region_2depth_name: "gu",
region_3depth_name: "legal_dong",
address_name: "address",
usage: "usage",
lat: "lat",
lng: "lng"
})
}
return (
<div>
onClick={addData}>
Add dataset
</button>
<CSVLink data={data} headers={headers}>
Download me
</CSVLink>;
</div>
);
}
export default App;
You have to use useState hook setData properly to add properly on the data array.
const addData = () => {
setData((oldData) => [
...oldData,
{
region_2depth_name: 'gu',
region_3depth_name: 'legal_dong',
address_name: 'address',
usage: 'usage',
lat: 'lat',
lng: 'lng',
},
]);
};
You can check here for the running code:
https://stackblitz.com/edit/react-84emed?file=src/App.js

State exists but not a function error happens. this.setState is not a function

State is existing but "not a function error" happens.
I am developing a component with React Tag.
The function is exists
I have no idea what it is wrong..
Error says
TypeError: this.setState is not a function
class ReagtTagSample extends Component {
constructor(props) {
super(props);
this.state = {
tags: [{ id: 'Yugoslavia', text: 'Yugoslavia' }, { id: 'India', text: 'India' }],
suggestions: [
{ id: "England", text: "England" },
{ id: "Mexico", text: "Mexico" },
],
};
handleAddition(tag) {
this.setState((state) => ({ tags: [...state.tags, tag] }));
}
handleDrag(tag, currPos, newPos) {
const tags = [...this.state.tags];
const newTags = tags.slice();
newTags.splice(currPos, 1);
newTags.splice(newPos, 0, tag);
this.setState({ tags: newTags });
}
render() {
const { test } = this.props;
const { tags, suggestions } = this.state;
<ReactTags
tags={tags}
suggestions={suggestions}
handleDelete={this.handleDelete}
handleAddition={this.handleAddition}
handleDrag={this.handleDrag}
delimiters={delimiters}
/>
handleAddition should be an arrow function to rebind this otherwise is not a class reference
handleAddition = (tag) => {
this.setState((state) => ({ tags: [...state.tags, tag] }));
}
same applies for handleDrag

State Not Changing Properly In React Redux

I am new to React Redux I have initialized state which is properly displaying by calling its respective reducer which job to return the initialize State. But after mutating the state the state most probably not changing and i cant figure it out why
import { combineReducers } from 'redux';
const initialState = {
songs:[
{title:'No Scrubs', duration: '4:05'},
]
}
const songReducers = (state = initialState)=>{
return state
}
const selectedSongReducer =(selectedSong=null,action)=>{
if(action.type==='SONG_SELECTED'){
return action.payload
}
return selectedSong;
}
const addSongReducer = (state=initialState,action)=>{
if(action.type==="ADD_SONG"){
return {
...state,
songs:[
...state.songs, {title:'All demo', duration: '4:05'}
]
}
}
return state;
}
export default combineReducers({
songs: songReducers,
selectedSong: selectedSongReducer,
addSong:addSongReducer
})
Your overall state shape will look like
state = {
songs: {
songs: [
{ title: 'No Scrubs', duration: '4:05' },
]
},
selectedSong: null,
addSong: {
songs: [
{ title: 'No Scrubs', duration: '4:05' },
]
}
}
after the very first reducer call. Is this what you want? Asking because you have
state = {
songs: {
songs: [
{ title: 'No Scrubs', duration: '4:05' },
]
},
...
}
instead of just
state = {
songs: [
{ title: 'No Scrubs', duration: '4:05' },
]
...
}

React : Best way to put dummy content in a component

I want to prepare my component to receive an JSON object from the backend.
So in my main component, I've got a state :
constructor(props) {
super(props);
this.state = {
contributions : {
[
{
name: 'Test',
value: '1',
},
{
name: 'Test2',
value: '12',
},
]
}
render() {
const { contributions } = this.state;
return (
<MyComponent contributions={contributions} />
);
}
So now, I want to know the best solution to render my object in MyComponent so I can have for output :
<div>
<span class="name">Test</span>
<span class="value">1</span>
</div>
<div>
<span class="name">Test2</span>
<span class="value">12</span>
</div>
JSON objects are key-value pairs. So if you're saving the JSON to your state, it can look something like
this.state = {
contributions : {
"nameValuePairs":[
{
"name": 'Test',
"value": '1',
},
{
"name": 'Test2',
"value": '12',
},
]
}
Now to map through the objects you can do something like
{this.state.contributions.nameValuePairs.map((item)=>(<TestChild item={item}/>))
Bascially your parent would look something like
import React, { Component } from 'react';
import TestChild from './TestChild'
class Test extends Component {
constructor(props) {
super(props);
this.state = {
contributions : {
"nameValuePairs":[
{
"name": 'Test',
"value": '1',
},
{
"name": 'Test2',
"value": '12',
},
]
}
}
}
render() {
return (
<div>
{this.state.contributions.nameValuePairs.map((item)=>(<TestChild item={item}/>))}
</div>
);
}
}
export default Test;
and your child component can have inside it, something like
render () {
return (
<div>{this.props.item.name}</div>
<div>{this.props.item.value}</div>
)
}
MyComponent
<div>
<span class="name">{this.props.name}</span>
<span class="value">{this.props.value}</span>
</div>
ParentComponent
constructor(props) {
super(props);
this.state = {
contributions : {
[
{
name: 'Test',
value: '1',
},
{
name: 'Test2',
value: '12',
},
]
}
render() {
const { contributions } = this.state;
return (
contributions && contributions.length && contributions.map(contrib => (
<MyComponent {...contrib) />
))
);
}

Resources