I develop cards in react js that card automatically generated based on API data but that all card shows one below other and I want to design that card in row fashion. I try many ways to design that card in row way but it is not done. I try inline CSS, some react-bootstrap class. So please give me some suggestions about how I can design this card.
class App extends React.Component {
elements = [];
state = {
data:[ null ]
};
getBikes = () => {
try {
return axios.get('URL')
} catch (error) {
console.error(error)
}
}
constructor(props) {
super(props);
this.props = props;
//this.elements=["one", "two", "three", "four"];
}
componentDidMount() {
const breeds = this.getBikes()
.then(response => {
if (response) {
console.log(response.data.message)
var arr = (response.data.message);
//var elements = [];
for (var i = 0; i < arr.length; i++) {
console.log(arr[i].bikeId)
this.elements.push(<div>
<Cards value={arr[i]} />
</div>);
}
this.setState({ data: arr[0].bikeId })
}
})
.catch(error => {
console.log(error)
})
}
render() {
console.log("printitng")
//const array = [1,2];
return (
<div style={{ display: "flex" }}>
<h1>{'This will always render'}</h1>
{this.state && this.state.data &&
this.state.map((item, index) => {
return <div key={index} style={{ width: "300px" }}>
<Cards elements={this.elements} /> //pass your props value
</div>
})
// < div >
// <Cards elements={this.elements} /> //pass your props value
// </div>
}
</div>
)
}
}
There's just one correction. You've pushed the elements of array with div which is a block element. You need push the elements with span or you can give class to the div and change from block to flex or inline block.
componentDidMount() {
const breeds = this.getBikes()
.then(response => {
if (response) {
console.log(response.data.message)
var arr = (response.data.message);
//var elements = [];
for (var i = 0; i < arr.length; i++) {
console.log(arr[i].bikeId)
// Changed from div to span
this.elements.push(<span>
<Cards value={arr[i]} />
</span>);
}
this.setState({ data: arr[0].bikeId })
}
})
.catch(error => {
console.log(error)
})
}
render() {
console.log("printitng")
return (
<div>
<h1>{'This will always render'}</h1>
{this.state && this.state.data &&
<div>
<Cards elements={this.elements} /> //pass your props value
</div>
}
</div>
)
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
bikeId : null,
data : []
}
}
getBikes = () => {
try {
return axios.get('URL')
} catch (error) {
console.error(error)
}
}
componentDidMount() {
const breeds = this.getBikes()
.then(response => {
if (response) {
this.setState({ data: response.data.message, bikeId: response.data.message[0].bikeId })
}
})
.catch(error => {
console.log(error)
})
}
render() {
return (
<div style={{ display: "flex" }}>
{
this.state.data.map((item, index) => {
return <div key={index} style={{ width: "300px" }}>
<Cards value={item} />
</div>
})
}
</div>
)
}
}
give parent class flex property then you can add as much child in a single row you can add.
Related
I'm new in React. I'm developing a screen but I have a issue, I don't know how insert the children in the parent if the state condition is equals, I'm using an array to print the parent and children but depends of the data the parent could have a children or not, for example if (parent.rework_name === children.rework_name) ? print the children : 'nothing in the parent'.
Please let me know if you have an idea how to solve this, many many thanks in advance.
This is the goal, my code works but the damn children is outside the parent :(
class Filling extends Component {
constructor() {
super();
this.state = {
fillingStations: [],
};
}
componentDidMount() {
getDataAPI('http://localhost:8080/api/parent')
.then((station) => {
getDataAPI('http://localhost:8080/api/children')
.then((data) => {
const stationArray = [];
station.map((item, index) => {
stationArray.push(
<ReworkStation key={index} title={index + 1} status='' />,
);
data.map((it, idx) => {
const f2Date = it.f2_time.substr(0, 10);
const f2Hour = it.f2_time.substr(11, 8);
const f2DateFormatted = `${f2Date.substr(8, 2)}/${f2Date.substr(5, 2)}/${f2Date.substr(0, 4)}`;
const color = selection_color(it.color_d);
return (
stationArray.push(item.rework_name === it.rework_name && <ReworkTitle key={idx} vin={it.vin} date={f2DateFormatted} ipsq={it.defects} hour={f2Hour} color={color} />)
);
});
});
console.log(stationArray);
this.setState({
fillingStations: stationArray,
});
});
});
}
render() {
return (
<div className='row'>
{ this.state.fillingStations }
</div>
);
}
}
I don't know how to insert the children inside the parent already render.
I already solved, first render all the parent divs and after replace the position array with array.splice
render() {
const array = [];
this.state.fillingStations.map((item, index) => (
array.push(<Parent key={index} title={index + 1} status='' />),
this.state.fillingChildren.map((it, ind) => {
if (item.name === it.name) {
parent.splice(index, 1,
<Parent {...this.props}}>
<Child {...this.props} />
</Parent >);
}
})
));
return (
<div className='row'>
{array}
</div>
);
}
}
I would like to get value from a child component (DropDown) and display them in a parent class (App),
I explain, I have a drop-down list that is imported into the App class, when I choose a value in this drop-down list I modify my data that is displayed in my class App,
class App :
class App extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
station: [],
stationValue: ''
}
}
getParking = async () => {
try {
const reponse = await axios.get(URL + "station/");
this.setState({
station: reponse.data['hydra:member']
});
} catch (e) {
console.log(e)
}
};
getData = async () => {
try {
const response = await axios.get(URL + "events?station=station_id");
this.setState({
data: response.data["hydra:member"]
});
} catch (error) {
console.log(error)
}
};
componentDidMount() {
this.getData();
this.getParking()
setInterval(this.appendData, 1000)
}
render() {
const {data, station} = this.state;
return (
<div>
<header>
<Dropdown dataStation={station}/>
</header>
{
data.map((item, key) =>
<div key={key}>
<>
{item.label}
</>
</div>
)
}
</div>
)
}
}
composent DropDown :
const Dropdown = ({dataStation}) => {
const [showMenu, setShowMenu] = useState(false);
const [selectItem, setSelectItem] = useState(showMenu);
const showList = () => {
setShowMenu(!showMenu)
};
const toggleSelected = (list) => {
setSelectItem(list.name);
setShowMenu(false)
};
return (
<>
<div className="dropdown-list-style" onClick={showList}>
<div style={{display: 'inline'}}>
{showMenu
? (<div style={{textAlign: 'right'}}><ChevronUp/></div>)
: (<div style={{textAlign: 'right'}}><ChevronDown/></div>)
}
{selectItem}
</div>
</div>
<div className="dropdown-list-style" style={{display: showMenu ? 'block' : 'none'}}>
{
dataStation.map((list, index) =>
<div key={index} onClick={() => toggleSelected(list)}>
{list.name}
</div>
)
}
</div>
</>
)};
So when I choose for example in the drop-down list the value "A", I will have to display the elements which are in "A", and "A" for example has a Id "1", and this id I will have to recover it and put it in my function (getData) which is in the class A. my code works when I put values written by hand for example when I put directly 1 in place of (station_id), but not when I wish to retrieve the id via the drop-down list.
Can you help me please?
inside your app component make callback that set the station value
setStation=(stationValue)=>{
this.setState({stationValue:stationValue})
}
passit to dropdown like this
<Dropdown dataStation={station} setStation={this.setStation}/>
inside dorpdow compoenent
uset it on click of item like:
{
dataStation.map((list, index) =>
<div key={index} onClick={() =>{toggleSelected(list); props.setStation(list)}}>
{list.name}
</div>
)
}
EDIT
you can use Station value in getData url like
getData = async () => {
try {
const response = await axios.get(URL + "events?station="+this.state.stationValue);
this.setState({
data: response.data["hydra:member"]
});
} catch (error) {
console.log(error)
}
};
I have a problem with my DropDown list with react, i want pre select a value in the list but i dont know how i can do it.
For exemple: before i select a value in the list, i want when get one before i select a value, for exemple the first element i get in my database.
class App :
class App extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
station: [],
stationValue: ''
}
}
getParking = async () => {
try {
const reponse = await axios.get(URL + "station/");
this.setState({
station: reponse.data['hydra:member']
});
} catch (e) {
console.log(e)
}
};
getData = async () => {
try {
const response = await axios.get(URL + "events?station=" + this.state.stationValue);
this.setState({
data: response.data["hydra:member"]
});
} catch (error) {
console.log(error)
}
};
componentDidMount() {
this.getData();
this.getParking()
setInterval(this.appendData, 1000)
}
setStation=(stationValue)=>{
this.setState({stationValue:stationValue})
}
render() {
const {data, station} = this.state;
return (
<div>
<header>
<Dropdown dataStation={station} setStation={this.setStation} value={this.handleChange}/>
</header>
{
data.map((item, key) =>
<div key={key}>
<>
{item.label}
</>
</div>
)
}
</div>
)
}
}
composent DropDown :
const Dropdown = ({dataStation, setParking, value}) => {
const [showMenu, setShowMenu] = useState(false);
const [selectItem, setSelectItem] = useState(showMenu);
const showList = () => {
setShowMenu(!showMenu)
};
const toggleSelected = (list) => {
setSelectItem(list.name);
setShowMenu(false)
};
return (
<>
<div className="dropdown-list-style" onClick={showList}>
<div style={{display: 'inline'}}>
{showMenu
? (<div style={{textAlign: 'right'}}><ChevronUp/></div>)
: (<div style={{textAlign: 'right'}}><ChevronDown/></div>)
}
{selectItem}
</div>
</div>
<div className="dropdown-list-style" style={{display: showMenu ? 'block' : 'none'}}>
{
dataStation.map((list, index) =>
<div key={index} onClick={() => toggleSelected(list); props.setStation(list)}}>
{list.name}
</div>
)
}
</div>
</>
)};
i tried something like
dataStation[0].name
but its not good, someone can help me please?
You can use useEffect hook. When the get request for the stations finishes and props change, it will select the first element from the array as the default value.
useEffect(() => {
if (Array.isArray(dataStation) && dataStation[0]) {
selectItem(dataStation[0].name);
}
}, [dataStation]);
I've created a React app for a school project that can add multiple types of input fields to a view by clicking a button (sort of like Wordpress Gutenberg).
Currently, I can add one of each type of item onto the view. However, if I click the button again, it erases the current text that was added. I'd like the ability to click the button to add as many fields as I'd like on click.
Also, the items are only added into the view in the order they were created meaning, even if I choose photo first and I click headline after, it (headline) will appear at the top of the list above the initial item.
I've had a look at these solutions (which were pretty good) but they didn't provide what I need.
Dynamically adding Input form field issue reactjs
and "update delete list elements using unique key": https://www.youtube.com/watch?v=tJYBMSuOX3s
which was closer to what I needed to do.
Apologies in advance for the length of the code,(there are two other related components for text input and an editform). I'm sure there is a much more simple way to do this. I haven't been able to find an npm package or solution to this specific problem online and am open to a simpler solution.
Edit.jsx
export default class Edit extends React.Component {
state = {
texts: {
hl: '',
shl: '',
txt: '',
photo: []
},
coms: {
hl: false,
shl: false,
txt: false,
photo: null
},
labels: {
// Replace with icons
hl: 'Headline',
shl: 'Sub',
txt: 'Text Area',
photo: 'Photo'
},
selectedItem: '',
}
componentDidMount() {
const saveData = localStorage.getItem('saveData') === 'true';
const user = saveData ? localStorage.getItem('user') : '';
this.setState({ user, saveData });
}
createPage = async () => {
await this.props.postPage(this.state.texts)
}
// add options
addOptions = (item) => {
const { coms } = this.state
coms[item] = !coms[item]
this.setState({ coms: coms })
}
// ADD TEXT
addTxt = () => {
this.setState({ texts: [...this.state.texts, ""] })
}
enableAllButtons = () => {
this.setState({ selectedItem: '' })
}
handleChange = (e, index) => {
this.state.texts[index] = e.target.value
//set the changed state.
this.setState({ texts: this.state.texts })
}
setDisable = (selectedItem) => {
this.setState({ selectedItem })
}
handleRemove = () => {
// this.state.texts.splice(index, 1)
this.setState({ texts: this.state.texts })
}
handleSubmit = (e) => {
console.log(this.state, 'all text')
}
handleChange = (e, item) => {
let { texts } = this.state
texts[item] = e.target.value
//set the changed state.
this.setState({ texts })
console.log(texts)
}
render() {
const { coms, labels, selectedItem, texts } = this.state
let buttons = Object.keys(coms)
let showItems = Object.keys(coms).filter(key => coms[key] === true)
return (
<div>
<InnerHeader />
{/* Make a route for edit here */}
<Route path='/edit/form' render={() => (
<EditForm
texts={texts}
coms={coms}
labels={labels}
addOptions={this.addOptions}
setDisable={this.setDisable}
selectedItem={selectedItem}
showItems={showItems}
handleChange={this.handleChange}
enableAllButtons={this.enableAllButtons}
/>
)} />
{/* Make route for preview */}
<Route path='/edit/preview' render={(props) => (
<Preview
{...props}
createPage={this.createPage}
/>
)}
/>
</div>
)
}
}
AddText.jsx:
export default class AddText extends Component {
state = {
}
// ADD TEXT
addTxt(item) {
const {
addOptions } = this.props
addOptions(item)
}
render() {
const { coms, labels } = this.props
const { selectedItem } = this.props
let buttons = Object.keys(coms)
console.log('here', selectedItem)
return (
<div>
<Card>
<Card.Body>
{
buttons.map((item, index) => <button
value={(selectedItem === "") ? false : (selectedItem === item) ? false : true} key={index} onClick={() => this.addTxt(item)}>
{labels[item]}
</button>
)
}
</Card.Body>
</Card>
</div>
)
}
}
EditForm.jsx
export default function EditForm(props) {
return (
<div>
<div className='some-page-wrapper-sm'>
<div className="dash-card-sm">
<button><Link to={{
pathname: '/edit/preview',
item: props.texts
}}>preview</Link></button>
<br />
<br />
<AddText
coms={props.coms}
labels={props.labels}
addOptions={props.addOptions}
setDisable={props.setDisable}
selectedItem={props.selectedItem}
/>
<div>
{
props.showItems.map((item, index) => {
return (
<InputFieldComponent
// setDisable={props.setDisable}
onChangeText={(e) => props.handleChange(e, item)}
enableAllButtons={props.enableAllButtons}
key={index}
item={item}
labels={props.labels}
texts={props.texts}
/>
)
})
}
</div>
</div>
</div>
</div>
)
}
InputFieldComponent.jsx
export default class InputFieldComponent extends React.Component {
setWrapperRef = (node) => {
this.wrapperRef = node;
}
render() {
const { labels, item, onChangeText, texts } = this.props
return (
<div>
<textarea
className="txt-box"
ref={this.setWrapperRef}
onChange={onChangeText}
placeholder={labels[item]}
value={texts[item]} />
</div>
)
}
}
The parent component Dashboard holds the state for every ListItem I add to my Watchlist. Unfortunately, every time I am adding an Item, it gets added to the DB, but only shows up when I refresh the browser.
class UserDashboard extends React.Component {
state = {
data: []
}
componentWillMount() {
authService.checkAuthentication(this.props);
}
isLoggedIn = () => {
return authService.authenticated()
}
getAllCoins = () => {
//fetches from backend API
}
addWishlist = () => {
this.getAllCoins()
.then(things => {
this.setState({
data: things
})
})
console.log("CHILD WAS CLICKED")
}
componentDidMount() {
this.getAllCoins()
.then(things => {
this.setState({
data: things
})
})
}
render() {
return (
<div className="dashboard">
<h1>HI, WELCOME TO USER DASHBOARD</h1>
<SearchBar
addWishlist={this.addWishlist}
/>
<UserWatchlist
data={this.state.data}
/>
</div>
);
}
}
The User Watchlist:
class UserWatchlist extends React.Component {
constructor(props) {
super(props)
}
// componentDidUpdate(prevProps) {
// if (this.props.data !== prevProps.data) {
// console.log("CURRENT", this.props.data)
// console.log("PREVs", prevProps.data)
// }
// }
render() {
return (
<div>
<h2>These are tssssyou are watching:</h2>
<ul className="coin-watchlist">
{
this.props.data.map((coin, idx) => {
return <ListItem key={idx}
coin={coin.ticker}
price={coin.price}
/>
})
}
</ul>
</div>
)
}
}
The search Bar that shows potential Items to watch over:
class SearchBar extends React.Component {
constructor(props) {
super(props)
this.state = {
coins: [],
searchValue: ""
}
}
searchHandler = e => {
e.preventDefault()
const value = e.target.value
this.setState({
searchValue: value
});
if (value === "") {
this.setState({
coins: []
})
} else {
this.getInfo()
}
}
getInfo = () => {
// Searches the API
}
addWishlist = () => {
this.props.addWishlist();
}
render() {
const {coins, searchValue} = this.state
return (
<div className="coin-search">
<form>
<input
type="text"
className="prompt"
placeholder="Search by ticker symbol"
value={searchValue}
onChange={this.searchHandler}
/>
</form>
<ul className="search-suggestions">
{
coins.filter(searchingFor(searchValue)).map( coin =>
<Currency
coin={coin}
addWishlist={this.addWishlist}
/>
)
}
</ul>
</div>
);
}
}
And the actual Currency that gets clicked to be added:
class Currency extends React.Component {
addToWatchlist = () => {
// POST to backend DB to save
};
fetch("/api/add-coin", settings)
.catch(err => {
return err
})
}
clickHandler = () => {
this.addToWatchlist()
this.props.addWishlist()
}
render() {
return(
<div className="search-results">
<li>
<h3> { this.props.coin.currency } </h3>
<button
className="add-to-list"
onClick={this.clickHandler}
>
+ to Watchlist
</button>
</li>
</div>
)
}
}
As you can see, I am sending props down all the way down to child. When I click the button to Add to Watchlist, I see the console.log message appear, saying "CHILD WAS CLICKED". I've even tried just calling the method to fetch from backend API again.
Also, in UserWatchlist, I've tried a componentDidUpdate, but both prevProps and this.props show the very same array of data. Somewhere in the chain, my data is getting lost.
This is also my first time posting a question here, so if it can be improved, I am happy to add extra details and contribute something to this community
You probably forgot to wait for addToWatchlist to complete:
addToWatchlist = () => {
// POST to backend DB to save
return fetch("/api/add-coin", settings)
.catch(err => {
return err
})
}
clickHandler = () => {
this.addToWatchlist().then(() => {
this.props.addWishlist()
})
}