React passing props through a class that extends React.component - javascript

I have two very simple react components, QF and Child. I am trying to pass data from a json file I have to the Child class, but I keep getting a 'props' is not defined error. I feel like I'm missing something small, but my React knowledge isn't strong enough for me to find it. Is there a different way I should be passing a prop to a child component? Thank you in advance!
I am a little confused since I keep seeing different ways to set up React components.
Here is the parent component:
import React from "react";
import Child from "./Child";
import Records from "./CriterionQuestions.json";
class QF extends React.Component {
state = {
response: "",
};
handleCallback = (childData) => {
this.setState({ response: childData });
};
render() {
let applicableCriteria = [];
// Push all possible criteria to list
for (let q = 0; q < Records.length; q++) {
for (let c = 0; c < Records[q].criterion.length; c++) {
applicableCriteria.push(Records[q].criterion[c]);
}
}
const idVals = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const resData = [
{ id: 1, response: "" },
{ id: 2, response: "" },
{ id: 3, response: "" },
{ id: 4, response: "" },
{ id: 5, response: "" },
{ id: 6, response: "" },
{ id: 7, response: "" },
{ id: 8, response: "" },
{ id: 9, response: "" },
];
const { response } = this.state;
return (
<div>
<h1> Questionnaire </h1>
<Child
parentCallback={this.handleCallback}
questionText={Records[0].question}
/>
{response}
</div>
);
}
}
export default QF;
And here is the child component:
import React from "react";
class Child extends React.Component {
onTrigger = (event) => {
this.props.parentCallback(event.target.booleanResponse.value);
event.preventDefault();
};
render() {
return (
<div>
<label>{props.questionText}</label>
<form onSubmit={this.onTrigger}>
<select name="booleanResponse" id="booleanResponse">
<option value="No">No</option>
<option value="Yes">Yes</option>
</select>
<br></br>
<br></br>
<input type="submit" value="Submit" />
<br></br>
<br></br>
</form>
</div>
);
}
}
export default Child;

Related

React: Storing <select> responses in a dictionary

I am in the process of creating a questionnaire. I currently have 9 questions (hence resData having id values ranging from 1-9. I have a child component, Child, that represents the question text and selection, but these components are iteratively rendered within the parent component, QF (questionnaire form).
Here is the parent component:
import React from "react";
import Child from "./Child";
import Records from "./CriterionQuestions.json";
class QF extends React.Component {
state = {
response: "",
};
handleCallback = (childData) => {
this.setState({ response: childData });
};
render() {
let applicableCriteria = [];
// Push all possible criteria to list
for (let q = 0; q < Records.length; q++) {
for (let c = 0; c < Records[q].criterion.length; c++) {
applicableCriteria.push(Records[q].criterion[c]);
}
}
const idVals = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const resData = [
{ id: 1, response: "" },
{ id: 2, response: "" },
{ id: 3, response: "" },
{ id: 4, response: "" },
{ id: 5, response: "" },
{ id: 6, response: "" },
{ id: 7, response: "" },
{ id: 8, response: "" },
{ id: 9, response: "" },
];
const { response } = this.state;
return (
<div>
<h1> Questionnaire </h1>
<form>
{resData.length > 0 &&
resData.map((id, index) => (
<Child
questionText={Records[index].question}
name={`resData.${index}.value`}
parentCallback={this.handleCallback}
></Child>
))}
<button type="submit">Click to submit</button>
</form>
</div>
);
}
}
export default QF;
And here is the child component:
import React from "react";
class Child extends React.Component {
onTrigger = (event) => {
this.props.parentCallback(event.target.booleanResponse.value);
event.preventDefault();
};
render() {
return (
<div>
<label>{this.props.questionText}</label>
<br></br>
<select name="booleanResponse" id="booleanResponse">
<option value="No">No</option>
<option value="Yes">Yes</option>
</select>
{this.onTrigger}
<br></br>
</div>
);
}
}
export default Child;
My goal is to store the response from booleanResponse and store it in resData (e.g., if question 1 is Yes then the response's value for id=1 would be Yes). However, I'm having some trouble with moving this information between the parent and child components. I've started messing with some handlers, but I don't think I have it quite right. How should I be performing a task like such? I'm still learning React, so sorry if the code is a bit messy.

react-sortable-tree - How to get the search API working

According to the API doc there needs to be a searchQuery prop which i've mentioned in my code but the search doesn't seem to be working
API doc doesn't explain how to implement it and the examples available online don't seem to be working on code sandbox.
The only article available which seems to explain search has incorrect code (duplicate props): https://frugalisminds.com/how-to-create-react-sortable-tree/
API Doc: https://www.npmjs.com/package/react-sortable-tree
Below is the code:
import React, { Component } from "react";
import SortableTree from "react-sortable-tree";
import "react-sortable-tree/style.css";
export default class Tree extends Component {
constructor(props) {
super(props);
this.state = {
treeData: [
{ title: "Chicken", children: [{ title: "Egg" }] },
{ title: "Fish", children: [{ title: "fingerline" }] },
],
searchString: ""
};
}
handleSearchOnChange = e => {
this.setState({
searchString: e.target.value,
});
};
render() {
return (
<div style={{ height: 400 }}>
<input
type="search"
onChange={this.handleSearchOnChange}
className="form-control"
/>
<SortableTree
searchQuery={this.state.searchString}
treeData={this.state.treeData}
onChange={treeData => this.setState([...treeData])}
isVirtualized={false}
/>
</div>
);
}
}
missing a searchFocusOffset to highlight the found item and a searchMethod which can be custom defined inside render method as follows:
import React, { Component } from "react";
import SortableTree from "react-sortable-tree";
import "react-sortable-tree/style.css"; // This only needs to be imported once in your app
export default class Tree extends Component {
constructor(props) {
super(props);
this.state = {
treeData: [
{ title: "Chicken", children: [{ title: "Egg" }] },
{ title: "Fish", children: [{ title: "fingerline" }] },
],
searchString: ""
};
}
render() {
// Case insensitive search of `node.title`
const customSearchMethod = ({ node, searchQuery }) =>
searchQuery &&
node.title.toLowerCase().indexOf(searchQuery.toLowerCase()) > -1;
return (
<div style={{ height: 400 }}>
<input
type="search"
onChange={event => this.setState({ searchString: event.target.value })}
className="form-control"
/>
<SortableTree
searchMethod={customSearchMethod}
searchQuery={this.state.searchString}
searchFocusOffset={0}
treeData={this.state.treeData}
onChange={treeData => this.setState([...treeData])}
isVirtualized={false}
/>
</div>
);
}
}

How can i solve the problem from the book road to react at page 78 ? I keep getting undefine for one of the methods in the table component

import React, { Component } from 'react';
import './App.css';
const list = [
{
title: 'React',
url: 'https://facebook.github.io/react/',
author: 'Jordan Walke',
num_comments: 3,
points: 4,
objectID: 0,
},
{
title: 'Redux',
url: 'https://github.com/reactjs/redux',
author: 'Dan Abramov, Andrew Clark',
num_comments: 2,
points: 5,
objectID: 1,
},
];
class App extends Component {
state = {
list,
text: 'abc',
searchTerm: ''
}
onDisMiss = (id) => {
const updateList = this.state.list.filter((item) => item.objectID != id)
return () => this.setState({ list: updateList })
}
onSearchChange = (event) => {
this.setState({ searchTerm: event.target.value })
}
isSearched = (searchTerm) => {
return (item) => item.title.toLowerCase().includes(searchTerm.toLowerCase())
}
render() {
const { searchTerm, list } = this.state
return (
<div>
<Search value={searchTerm}
onChange={this.onSearchChange}>Search</Search>
<Table list={list} pattern={searchTerm} onDissMiss={this.onDisMiss} />
</div>
);
}
}
class Search extends Component {
render() {
const { value, onChange, children } = this.props
return (
<div>
<form>
{children}<input type="text" onChange={onChange} value={value} />
</form>
</div>
);
}
}
class Table extends Component {
render() {
const { list, pattern, onDisMiss } = this.props
return (
<div>
{list.filter(isSearched(pattern)).map(item =>
<div key={item.objectID}>
<span><a href={item.url}>{item.title}</a></span>
<span>{item.author}</span>
<span>{item.num_comments}</span>
<span>{item.points}</span>
<span>
<button onClick={onDisMiss(item.objectID)} type="button">Dismiss</button>
</span>
</div>)
}
</div>
);
}
}
export default App;
Road to react Book The Table component related.I get undefined for the isSearched method. how can I fix it so it works correctly its from the book road to react it seems like the book has a few error which I have problems solving because am just learning react. can you help with the solution and why this problem is actually happening
You should put the isSearched method inside the Table class and not the App class

Way to pass props and display in a list in react

I am encountering issues when trying to display the props in an ordered list. It only displays the initial value. When I add to the list, it was not updated.
Here is the source code
TodoList.js
class ToDoList extends React.Component {
render() {
return (
<div>
{this.props.data.map(list => {
return (
<ol key={list.uuid} > <input type="checkbox"></input>{list.uuid}- {list.text}</ol>
);
})}
</div>
);
}
}
export default ToDoList;
Todo.js
let data = [{ uuid: 100, text: "TEST" }, { uuid: 101, text: "TEST" }];
let id = 0;
class Todo extends React.Component {
handleAddItem = () => {
id = id + 1;
data.push({ uuid: id, text: this.refs.textInput.value });
console.log(data);
}
render() {
return (
<div>
<div>
<input type="text" ref="textInput"></input>
<button onClick={this.handleAddItem}>ADD TO LIST</button>
</div>
<ToDoList data={data} />
</div>
);
}
}
export default Todo;
Thank you.
When I add to the list, it was not updated.
It's because data is not a state variable and does not cause a re-render.
To fix, make it a state instead.
class Todo extends React.Component {
// make data and id a state variable
state = {
data: [{ uuid: 100, text: "TEST" }, { uuid: 101, text: "TEST" }],
id: 0,
}
...
}
Then pass state data to TodoList
<ToDoList data={this.state.data} />
WHEN UPDATING STATE:
Never mutate a state variable in your handler by using spread operator (...).
handleAddItem = () => {
// update the state using this.setState()
this.setState(prevState => ({
id: prevState.id + 1,
data: [
...prevState.data, // use spread operator
{ uuid: prevState.id + 1, text: this.refs.textInput.value }
]
}),
() => console.log(this.state.data) // pass 2nd arg to log state update
);
}
You should add state to ToDo component add use setSate() method to update state. Then the ToDo component and ToDoList component will re-render.
let data = [{ uuid: 100, text: "TEST" }, { uuid: 101, text: "TEST" }];
let id = 0;
class Todo extends React.Component {
state = {
data
}
handleAddItem = () => {
id = id + 1;
this.setSate({
data: [...this.state.data, { uuid: id, text: this.refs.textInput.value }]
});
console.log(this.state.data);
}
render() {
return (
<div>
<div>
<input type="text" ref="textInput"></input>
<button onClick={this.handleAddItem}>ADD TO LIST</button>
</div>
<ToDoList data={this.state.data} />
</div>
);
}
}
There is the doucment about Component State. Read it to learn more.

I am not able to remove the list item when i click dismiss?

There are no errors in the code, what is the problem?
I am not able to dismiss the list items and change the state for my component!
What should i do to make my dismiss work and is there a better way as above to do so ??
Here is the code :
import React, { Component } from 'react';
import './App.css';
const list = [
{
title: 'React',
url: 'https://facebook.github.io/react/',
author: 'Jordan Walke',
num_comments: 3,
points: 4,
objectID: 0,
},
{
title: 'facebook github',
url: 'https://facebook.github.io/',
author: 'Janardhan',
num_comments: 3,
points: 6,
objectID: 1,
},
]
class App extends Component {
constructor(props) {
super(props);
this.state = {
list
}
this.onDismiss = this.onDismiss.bind(this);
}
onDismiss(id) {
const isNotID = item => item.objectID !== id;
const updatedList = this.state.list.filter(isNotID)
this.setState({ list: updatedList })
console.log("dismissed??")
}
render() {
return (
<div className="App">
{list.map(item =>
<div key={item.objectID}>
<span>
<a href={item.url}>{item.title}</a>
</span>
<span>{item.author}</span>
<span>{item.points}</span>
<span>{item.num_comments}</span>
<button onClick={() => this.onDismiss(item.objectID)} >Dismiss</button>
</div>
)}
</div>
);
}
}
export default App;
the problem comes from here :
const isNotID = item => item.objectId !== id;
it should be objectID not objectId
Edit
And in the render method, it should be this.state.list.map

Categories