import { Dropdown, Button } from 'antd';
import { memo } from 'react';
import type { MenuProps } from 'antd';
const headerMeau: MenuProps['items'] = [
{
key: '1',
label: 'test'
},
{
key: '2',
label: 'test2'
},
{
key: '3',
label: 'test3'
}
];
const A = function () {
return <Button>111</Button>;
};
const BookSpace = memo(() => {
return (
<Dropdown menu={{ items: headerMeau }} placement="bottomLeft" trigger={['click']}>
<A></A>
{/* {A()} */}
</Dropdown>
);
});
BookSpace.displayName = 'BookSpace';
export default BookSpace;
It doesn't work when it is < A > < / A >
It normal when it is {A()}
expected:when the child is a React Component it's normal
enter image description here
It's because Dropdown component is the container for Button component and the actual Menu.
When you write a custom wrapper for Button, Dropdown doesn't know what to do with it. Because it is not a Button component anymore, it is a custom A component that wraps some JSX or Button components.
But when you do {A()} it returns the actual Button component of AntD and it works as intended.
Related
Im using galio's radio component this here. Im trying to select only one value at a time. I try to achieve that with this code:
const [selected, setSelected ] = useState(false);
const OptionList = (groupOption) => {
return (
<FlatList
data={groupOption.options}
keyExtractor={(result) => result.id.toString()}
renderItem={({ item }) => {
return (
<View>
<Radio label={item.description} onChange={() => setSelected(true)} initialValue={selected} />
</View>
);
}}
/>
);
};
But since its in a flat list it changes the value for all of them. How can i only select one radio button at a time? Any ideas?
Use Radio Group or save the selected index in the state, when the user clicks on the radio button, change that selected index and mark it selected.
https://www.npmjs.com/package/react-native-radio-buttons-group I think that's what you are looking for
an example
import React, { useState } from 'react';
import RadioGroup from 'react-native-radio-buttons-group';
const radioButtonsData = [{
id: '1', // acts as primary key, should be unique and non-empty string
label: 'Option 1',
value: 'option1'
}, {
id: '2',
label: 'Option 2',
value: 'option2'
}]
export default function App() {
const [radioButtons, setRadioButtons] = useState(radioButtonsData)
function onPressRadioButton(radioButtonsArray) {
setRadioButtons(radioButtonsArray);
}
return (
<RadioGroup
radioButtons={radioButtons}
onPress={onPressRadioButton}
/>
);
}
can anyone help me how to do to be able change a stat of 'reserved' from true to false in dummy data in home.js from modalDetails.js ?
https://github.com/FikVlk/Vozickov
This works I believe. I added a button to log your state before and after the change so you can verify that it works. Feel free to remove it, of course.
import React, { useState } from 'react';
import { StyleSheet, Text, View, FlatList, Button } from 'react-native';
import ItemList from './itemList';
import Card from '../components/card';
import { globalStyles } from '../Styles/globalStyles';
export default function home({ route, navigation }) {
const [list, setList] = useState([
{
title: 'Kishal',
body: 'asdasdd',
reserved: true,
id: '1',
},
{
title: 'Kishal',
body: 'asdasdd',
reserved: false,
id: '2',
},
]);
if (route.params) {
for (let i = 0; i < list.length; i++) {
if (list[i][id] === route.params[id]) {
if (list[i].reserved !== route.params.reserved) {
setList((prevList) => {
const copy = [...prevList];
copy[i].reserved = route.params.reserved;
return copy;
});
}
}
}
}
const reserveCar = () => {
console.log('yes');
};
return (
<View styles={globalStyles.container}>
<FlatList
data={list}
renderItem={({ item }) => (
<Card>
<ItemList item={item} navigation={navigation} />
</Card>
)}
/>
<Button title="LOG STUFF" onPress={() => console.log(list)} />
</View>
);
}
const styles = StyleSheet.create({});
The easier and better way is to put the state you have in the home component into redux. This is logical because both the modal and your home component need access to the list and need to know which ones are reserved. It also seems likely that more components will need this information in the future as it seems to be one of the main functions of the app you're building.
You can find documentation about react-redux here: https://react-redux.js.org/using-react-redux/connect-mapstate. It's a rather complicated thing to learn, but exceptionally useful after you've learned it.
Stephen Grider has a great video that's the best explanation I've seen. Link: https://www.youtube.com/watch?v=3sjMRS1gJys
Inside of my react application there are two components
Navbar
import React, { Component } from 'react';
import NavLink from './navlink';
class Navbar extends Component {
state = {
links: [
{
title: "Music",
active: false
},
{
title: "Home",
active: false
},
{
title: "Discord",
active: false
}
]
}
updateNavlinks = title => {
const links = this.state.links
for (const link in links){
if (links[link].title != title){
links[link].active=false;
}
else{
links[link].active=true;
}
}
console.log(links);
this.setState({links})
};
render() {
return (
<div id="Navbar">
{this.state.links.map(link => <NavLink key={link.title} title={link.title} active={link.active} onClickFunc={this.updateNavlinks}/>) }
</div>
);
}
}
export default Navbar;
Navlink
import React, { Component } from 'react';
class NavLink extends Component {
state = {
className: "navlink"+ (this.props.active?" active":"")
}
render() {
return (
<div className={this.state.className} onClick={() => this.props.onClickFunc(this.props.title)}>
{this.props.title}
</div>
);
}
}
export default NavLink;
My intention is to create a navbar where if the user selects a page, that <Navlink /> has its state changed. Once its state is changed (active=true), I want the classname to change, adding the "active" class and giving it the styles I want.
When updateNavlinks() is called, the state in <Navbar /> is changed, but it doesn't cause a visual change in the associated <Navlink />
Where did I go wrong with this? Is there a more simple way to accomplish this?
Here, you're mutating the existing state:
updateNavlinks = title => {
const links = this.state.links
for (const link in links){
if (links[link].title != title){
links[link].active=false;
}
else{
links[link].active=true;
}
}
console.log(links);
this.setState({links})
};
Never mutate state in React - that can make the script behave unpredictably. You need to call setState with a new object instead, so React knows to re-render:
updateNavlinks = titleToMakeActive => {
this.setState({
links: this.state.links.map(
({ title, active }) => ({ title, active: title === titleToMakeActive })
)
});
};
Another problem is that you're assigning state in the constructor of the child component in NavLink:
class NavLink extends Component {
state = {
className: "navlink"+ (this.props.active?" active":"")
}
render() {
return (
<div className={this.state.className} onClick={() => this.props.onClickFunc(this.props.title)}>
{this.props.title}
</div>
);
}
}
This assigns to the state own-property when the component is mounted, but the component doesn't get un-mounted; the instance doesn't change, so state doesn't get assigned to again, even when the props change.
To fix it, reference the props inside render instead of using state:
class NavLink extends Component {
render() {
return (
<div className={"navlink"+ (this.props.active?" active":"")} onClick={() => this.props.onClickFunc(this.props.title)}>
{this.props.title}
</div>
);
}
}
I have a multiple select. Instead of using the default behaviour I am showing the total selected items in the input when there are any values selected.
The problem is that I want also to be able to type for search when some items are selected. I have managed to do that by returning the last children item from CustomValueContainer . But it's still not enough.
What I would like to do is to show the total items when the input has no focus, and hide it when the input is focused. So I need to get the reference to the input value from my CustomValueContainer in order to see if it's focused or not. Any ideas?
This is my code https://stackblitz.com/edit/react-hv89pn:
import React, { Component } from 'react';
import { render } from 'react-dom';
import Select, { components as selectComponents, ValueContainerProps } from 'react-select';
import './style.css';
const CustomValueContainer = (props) => {
const length = props.getValue().length;
const children = props.children;
return length ? (
<selectComponents.ValueContainer {...props}>
<>
{length} selected
{children.slice(-1)}
</>
</selectComponents.ValueContainer>
) : (
<selectComponents.ValueContainer {...props}>{children}</selectComponents.ValueContainer>
);
};
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
render() {
return (
<Select
options = {[
{value: "1", label: "one"},
{value: "2", label: "two"},
{value: "3", label: "three"},
{value: "4", label: "four"},
]}
value={this.state.value}
onChange={value => this.setState({ value })}
isMulti
components={{ValueContainer: CustomValueContainer}}
clearable={true}
closeMenuOnSelect={false}
openMenuOnFocus={true}
/>
);
}
}
render(<App />, document.getElementById('root'));
Note that CustomValueContainer needs to be declared outside the render method (it does not work otherwise), but it's possible to pass a paremeter to it from render, I just need to pass it as a property of React Select and retrieve it from CustomValueContainer using props.selectProps.
I'm using AntD components to build a table and one of my columns consists of the InputNumber component. I would like the InputNumber component to have a default value that is contained in a prop that is passed to the table component. However I'm unsure how to access the props from the parent, or more specifically pass them to the InputNumber component as the render prop for the columns exists outside of the table component. Here is an example of the code
import React, { Component } from 'react';
import { Table, Divider, InputNumber } from 'antd';
const pageSize = 30; // Page size to show pagination
const reqColumns = [
{
title: 'Filled',
dataIndex: 'slotFilled',
editable: false,
},
{
title: 'Required',
dataIndex: 'slotMinimum',
render: () => (
<InputNumber min={0}/>
),
},
];
export default class RequirementsTable extends Component {
render() {
return (
<div>
<Divider type="horizontal" orientation="left">
Requirements
</Divider>
<Table
rowKey="senateShortname"
bordered
dataSource={this.props.data}
columns={reqColumns}
pagination={1 > pageSize && { pageSize }}
size="small"
/>
</div>
);
}
}
I've attempted to set the defaultValue = {this.props.data} but of course that points to the props of the InputNumber.
The AntD table already was attempting to pass the value to the cell. The solution was quite simple.
{
title: 'Required',
dataIndex: 'slotMinimum',
render: (value) => (
<InputNumber min={0} defaultValue={value}/>
),
},