I have a User Resource, which referenced by many other resources.
So I want to create a UserResourceInput :
import React from 'react';
import {ReferenceInput, SelectInput} from 'admin-on-rest';
const UserReferenceInput = (props) => (
<ReferenceInput reference="user" {...props}>
<SelectInput optionText="name"/>
</ReferenceInput>
);
UserReferenceInput.defaultProps = {
source: 'userId',
addLabel: true,
label: 'User'
};
export default UserReferenceInput;
And Use it in simple form like this:
ProductCreate = (props) => (
<Create {...props}>
<SimpleForm>
<TextInput source="title" />
<NumberInput source="price" />
<UserReferenceInput />
</SimpleForm>
</Create>
);
But I get this Error:
You are missing the source prop on the ReferenceInput. Hence, it can't find value for it. You can define it either inside the UserReferenceInput directly or pass it as prop to the UserReferenceInput in your form.
Edit
Don't use the addLabel prop on the ReferenceInput, it does not support it. Instead, apply it on the SelectInput child.
Related
What I am trying to achieve is focusing on TextInput present in child component when clicked on an icon present in parent file. I have tried using refs and forward refs but that means i have to wrap the component in forwardref which i am trying to avoid.
const InputText = React.forwardRef((props, ref) => (
<input ref={ref} {...props} />
));
My child file looks like this:
export const TextField = ({
label,
placeholder = "",
id = "",
isSecure = false,
disabled = false,
handleBlur,
handleChange,
value,
...props
}: IProps): React.ReactElement => {
const { labelStyle, fieldStyle, status=false, search=false,inputStyle, errorStyle } =
props;
//some statements
<View style={styles.elementsContainer}>
<TextInput //I want to focus on this
.......
.
.
onChangeText={handleChange(props.name)}
onBlur={handleBlur(props.name)}
/>
</View>
);
};
export default TextField;
Below is my parent file where I have an icon and on click of it I trying this textfield to be focused.
return (
<Formik
initialValues={initialValues}
onSubmit={(values, { setSubmitting }) => {
setSubmitting(false);
}}
>
{(formikProps: FormikProps<{ searchText: string }>) => (
<View style={status?styles.highlight:[styles.container,textFieldDimensions]}>
<TouchableOpacity onPress={addressFocus}> //This is the icon on click of it i am trying textfield child component to be focused.
<Icon testID="home" name={IconNames.home} />
</TouchableOpacity>
<View style={styles.textfieldContainer}>
<TextField //CHild component
handleChange={formikProps.handleChange}
status={status}
handleBlur={() => searchFunction(formikProps.values.searchText)}
value={formikProps.values.searchText}
name="searchText"
placeholder={placeholder}
search={search}
label="Search :"
id="searchText"
fieldStyle={[styles.field,fieldStyle]}
inputStyle={styles.input}
labelStyle={[styles.label, labelStyle]}
/>
</View>
</View>
)}
</Formik>
);
So after brainstorming i come to a simple approach which works for me as of now. But i am not crystal clear from ref part how its working.
so what i did is in parent file where i am passing props in child component like this:
const toggle=()=>{
setToggler(!toggler) This function changes state value which is boolean type from false to true and vice versa.
}
<TouchableOpacity onPress={toggle}> //toggle function called on onPress
<Icon testID="home" name={IconNames.home} />
</TouchableOpacity>
<TextField
toggler={toggler} //Now I am passing state toggler into child component, change of this state will re render the component
handleChange={formikProps.handleChange}
status={status}
handleBlur={() => searchFunction(formikProps.values.searchText)}
value={formikProps.values.searchText}
name="searchText"
placeholder={placeholder}
search={search}
label="Search :"
id="searchText"
fieldStyle={[styles.field,fieldStyle]}
inputStyle={styles.input}
labelStyle={[styles.label, labelStyle]}
/>
Now how i am handling refs in child component is that it focus on textinput on click of button.
All this is happening in functional component, for simplicity react rules has not been taken into account only relevant pieces of code is shown
const inputRef = useRef<TextInput>(null);
const onClickFocus = () => {
{props.toggler && inputRef.current?.focus();} //If toggler changes to true then this function will execute and perform inputRef.current?.focus();
}
onClickFocus() //Function is called here and later inputRef is utilized in textinput as ref={inputRef}
<TextInput
ref={inputRef}
placeholder={placeholder}
secureTextEntry={isSecure}
style={search? fieldStyle:[styles.inputBox, inputStyle]}
editable={!disabled}
value={value}
{...field}
onChangeText={handleChange(props.name)}
onBlur={handleBlur(props.name)}
/>
I am currently working on a project with React Hooks.
Parent component is a Navigator
Child component is a breadcrumb display in this navigator.
Child component fetches and displays a view with the data.
How can i use the response data in the 2. child component to set name in the 1. Child component?
My Code (omitted large portions of unnecessary code for this example):
Navigator
const { Header, Content } = Layout;
const Navigation = (props: any) => (
<>
<Layout>
<Layout>
<Header>
<Breadcrumbs
style={{ flexGrow: 2, paddingLeft: 20 }}
name='Name of User'
/>
</Header>
<Content style={{ margin: '24px 16px 0', overflow: 'hidden' }}>
<div className="content">
<Switch>
<Route exact path="/" component={MyPatients} />
<Route exact path="/Skjema" component={MySchemas} />
<Route
exact
path="/Pasient"
component={() =>
<PatientInfo
patientID={props.history.location.state}
/>
}
/>
export default withRouter(Navigation);
BreadCrumbs
import React from 'react';
import Breadcrumb from 'antd/lib/breadcrumb';
import { HomeOutlined, UserOutlined } from '#ant-design/icons';
const Breadcrumbs = (props: any) => {
return (
<>
<div className="Breadcrumbcontainer" style={props.style}>
<Breadcrumb>
<Breadcrumb.Item href="/">
<HomeOutlined />
<span style={{ color: 'black' }}>Hjem</span>
</Breadcrumb.Item>
<Breadcrumb.Item href="Pasient">
<UserOutlined />
<span style={{ color: 'black' }}>
{props.name}
</span>
</Breadcrumb.Item>
<Breadcrumb.Item>
<span>Skjema 1 - 17.04.20</span>
</Breadcrumb.Item>
</Breadcrumb>
</div>
</>
);
};
export default Breadcrumbs;
The third file contains a fetch to an api and works fine, the data in question is currently stored as response.name How can i lift this info up to Navigator?
If I understood your question correctly, there's a parent component that has two child components and you want to trigger a change from one child component in another.
You can maintain the state in the parent component, pass state in child1 and setState function in child2.
// Parent Component
const [name, setName] = useState('');
<>
<child1 name={name}/>
<child2 setName={setName}/>
</>
Try this one. I added code sandbox and you can check it out is this what you need. So from parent pass hook as props to a child, and then after the request is made inside of the child component call function from props that will fill the data inside parent component.
Update state in parent from child
I found a solution thanks to the suggestions in this thread. I made my mistake in the passing of the files to the function.
const PatientInfo = ({ patientID, setName }: any) => {
console.log(useFetch<IPatient>( // name of endpoint.... ));
const { response } = useFetch<IPatient>(
'// name of endpoint.... + patientID,
patientID,
);
This ended up fixing my problem. The problem was i initially called the two seperately, like this:
const PatientInfo = ({ patientID }: any, { setName } : any) => {
console.log(useFetch<IPatient>( // name of endpoint.... ));
const { response } = useFetch<IPatient>(
'// name of endpoint.... + patientID,
patientID,
);
So this change worked, although I am not entirely sure as to why.
I am new to react-native. Here I am trying to add two buttons on headerRight. I did add one button but I could not figure out how to put more than one. Something like this.
I am using react-navigaiton and react-navigation-header-buttons.
This is how I added one button.
mainScreen
headerRight: (
<HeaderButtons HeaderButtonComponent={CustomHeaderButton}>
<Item
title={"Search"}
iconName={"md-search"}
onPress={() => {
console.log('Search')
}}
/>
</HeaderButtons>
),
CustomHeaderButton.js
import {HeaderButton, Item} from 'react-navigation-header-buttons';
import {Ionicons} from '#expo/vector-icons';
const CustomHeaderButton = props => {
return(
<HeaderButton
{...props}
IconComponent={Ionicons}
iconSize={23}
color={'black'}
/>
)
};
export default CustomHeaderButton;
You're on the right track. You should be able to simply add another Item with whatever title, icon, onPress functionality you want wrapped in the HeaderButtons component like this:
<HeaderButtons HeaderButtonComponent={CustomHeaderButton}>
<Item
title={"Search"}
iconName={"md-search"}
onPress={() => {
console.log('Search')
}}
/>
<Item
title={"Other Button"}
iconName={"other-icon-name"}
onPress={() => {
console.log('The other header icon was pressed.')
}}
/>
</HeaderButtons>
You are able to nest multiple React elements within a React element, which is what this example uses. For instance, you can nest multiple Text elements inside of a View.
It looks like you are using the react-navigation-header-buttons package, here is their example with multiple header icons for your reference as well: https://github.com/vonovak/react-navigation-header-buttons/blob/master/example/screens/UsageCustom.tsx
I am creating a wrapper component for icons that I import using react-icons. Here is an example of how it looks right now:
import { FaTwitter as Twitter} from 'react-icons/fa'
import { Icon } from './elements
<Icon>
<Twitter />
<Icon>
Now, this works just as I want it to -- but I would like to simplify the code. Ideally, I'd like it to look/work like this:
<Icon name='twitter' />
Any idea how to do this?
NOTE: In case it helps, here is current code for my Icon component:
export const Icon = props => <IconBase {...props} />
The <IconBase> component is just some styles from styled-components.
UPDATE
I just want to note that the Twitter example is just that -- an example. I'm looking for a solution that will work no matter what name I pass to the <Icon> component. So, in other words, all of the following (and more) will work:
<Icon name="Facebook" />
<Icon name="Search" />
<Icon name="Menu" />
Each of these would be equivalent to:
<Icon><Facebook /></Icon>
<Icon><Search /></Icon>
<Icon><Menu /></Icon>
In other words, no matter what icon I pull in from react-icons, it will render properly vis-a-vis the name prop.
What about this?
// definition:
const Icon = (props) => <SomeIconWrapper><props.glyph /></SomeIconWrapper>;
// usage:
<Icon glyph={Twitter} />
It is super simple and flexible, no need for any dictionary or so.
I think something like this would satisfy your condition.
const App = () => <Icon name="twitter" />;
const dict = { twitter: <Twitter /> };
const Icon = ({ name }) => <IconBase>{dict[name]}</IconBase>;
I created a basic component such as:
export default (props) => (
<TouchableOpacity {...props} style={styles.button}>
{props.title && <Text style={styles.text}>{props.title}</Text>}
{props.icon && <Icon name={props.icon} />}
</TouchableOpacity>
);
I can then call it with <Component title="Home" icon="home" /> for instance.
The problem is that passing {...props} to TouchableOpacity generate errors because it does not recognize title nor icon properly.
For instance:
JSON value 'Home' of type NSString cannot be converted to...
Is there a way to filter props so that I only pass valid ones for TouchableOpacity?
Transferring Props
Sometimes it's fragile and tedious to pass every property along. In that case you can use destructuring assignment with rest properties to extract a set of unknown properties.
List out all the properties that you would like to consume, followed by ...other.
var { checked, ...other } = props;
This ensures that you pass down all the props EXCEPT the ones you're
consuming yourself.
function FancyCheckbox(props) {
var { checked, ...other } = props;
var fancyClass = checked ? 'FancyChecked' : 'FancyUnchecked';
// `other` contains { onClick: console.log } but not the checked property
return (
<div {...other} className={fancyClass} />
);
}
ReactDOM.render(
<FancyCheckbox checked={true} onClick={console.log.bind(console)}>
Hello world!
</FancyCheckbox>,
document.getElementById('example')
);
Like Paul Mcloughlin, I would recommend using object destructuring along with a rest parameter. You can destructure your props object directly in your function parameters like so:
({title, icon, ...remainingProps}) => (...)
This extracts the title and icon props from your props object and passes the rest as remainingProps.
Your complete component would be:
export default ({title, icon, ...remainingProps}) => (
<TouchableOpacity {...remainingProps} style={styles.button}>
{title && <Text style={styles.text}>{title}</Text>}
{icon && <Icon name={icon} />}
</TouchableOpacity>
);