React select input as option - react-select

Im trying to create a generic Async React Select.
At the moment my Select is showing Suggestions (using entered mail) which are loaded via external API. The user is forced to select a suggestion.
In Future I also want to provide an individual Input possibility, where the user can enter a own mail without selecting a suggestion. I cant find any solutions for these issue.
Any help would help me a lot.
My React Select (Type Async)
export default class AsyncSelect extends Component {
constructor(props) {
super(props)
this.state = {
selectedOption: ""
}
this.handleChange = this.handleChange.bind(this)
this.loadOptions = this.loadOptions.bind(this)
}
handleChange(selectedOption){
this.setState({ selectedOption })
if(this.props.onOptionSelect){
this.props.onOptionSelect(selectedOption)
}
}
loadOptions(input, callback) {
this.props.loadOptions(input).then(options => {
callback(null, {options: options})
})
}
render() {
return (
<div className="form-group">
<Select.Async
value={this.state.selectedOption}
onChange={this.handleChange}
loadOptions={this.loadOptions}
isLoading={false}
placeholder={this.props.label}
/>
</div>
)
}
}
AsyncSelect.propTypes = {
value: PropTypes.string,
loadOptions: PropTypes.func.isRequired
}

instead of using Select.async you could use the HOC provided by the lib AsyncCreatable that allows you to choose a suggestion OR create a new entry.
check the readme of react-select for more details ;)

Related

React-admin: how to prevent getAll on page load

My use case:
On page load I need to show only filters and empty list.
RA should only make first request to API when user enter anything in one of the filters.
Didn’t found anything related in documentation.
If someone can just pinpoint me correct topic in docs, which I should dig better to achieve what I need, it already will help a lot.
Thank you!
You can't use the <List> component for that, as it makes requests on mount. You'll have to write your own List component and call the API using the useGetList hook, as explained in the documentation:
import { useGetList } from 'react-admin';
const LatestNews = () => {
const { data, ids, loading, error } = useGetList(
'posts',
{ page: 1, perPage: 10 },
{ field: 'published_at', order: 'DESC' }
);
if (loading) { return <Loading />; }
if (error) { return <p>ERROR</p>; }
return (
<ul>
{ids.map(id =>
<li key={id}>{data[id].title}</li>
)}
</ul>
);
};

React-admin - Cannot update a component (`xxx`) while rendering a different component (`SelectInput`)

React-admin 3.8.4
I'm rendering some form fields conditionally, and these fields have some validations. Because of this, I'm receiving this error below:
Warning: Cannot update a component (nameOfTheComponent) while rendering a different component
(SelectInput). To locate the bad setState() call inside SelectInput, follow the stack trace
as described in...
I already have read some explanation about the problem and I've discovered that react-final-form
calls a setState() when registering those fields and this seems to be the issue.
I also saw that there is a fix into FileConfig called silent that solves this problem React final form silent
But I don't know if I'm using wrong, because the warning remains showing up.
I'm trying to do something like this:
const OfferVariation = ({ formData, ...rest }) => {
const form = useForm();
useEffect(() => {
return () => {
const initialState = {}
let inConstructor = true
const fieldName = "internalOffer.type"
form.registerField(fieldName, fieldState => {
if (inConstructor) {
initialState[fieldName] = fieldState
} else {
this.setState({ [fieldName]: fieldState })
}
}, { silent: true })
}
}, [])
if (flowType === "Interna") {
return (
<SelectInput
source="internalOffer.type"
label="Tipo da Oferta"
choices={offerTypes}
validate={validateArrayNotEmpty}
{...rest}
/>
)
} else if (flowType === "Externa") {
return (
<TextInput
label="Url Externa"
source="externalOffer.externalURL"
{...rest}
/>
)
}
}
};
export default OfferVariation;
Does anyone know how to fix it and could help me?

React Native: How can I redirect after login to different pages depending on the type of account of a user?

I'm building a react native app using expo and I would like to know how I can send a "UserTypeA" to Homepage and send a "UserTypeB" to Profile upon login.
I have a UserTypeA tab navigator and a UserTypeB tab navigator, with just 2 pages that will be see able by both accounts.
I have my UserTypeA data and UserTypeB data in separate tables so I can identify which user has which type.
Sorry if it's not clear this is my first question.
Thank you for your help!
In your apps main render method, you could do something like this.
Basically, you will listen to your redux state and switch main screen depending on the user type.
class MyApp extends PureComponent {
constructor(props) {
super(props);
}
render() {
const { auth } = this.props;
if (auth.userObj.type1) {
return <Type1MainComponent />;
}
if (auth.userObj.type2) {
return <Type2MainComponent />;
}
return <LoginScreen />;
}
}
function mapStateToProps(state) {
const { auth } = state;
return { auth };
}
export default connect(mapStateToProps)(MyApp);

Navigation - Pass variable to other files

I'm new on React-Native and it's my first React-Native app. However, I have already some problems.
I want to pass a variable from one class (Home.js) to an another. (Is it possible without using the composent in the render() fonction ?)
##### Home.js #####
class Home extends Component {
constructor(props) {
super(props);
this.state = {direction: "defaultvalue"};
}
getCurrentDirection() {
return this.state.direction;
}
render() {
/***..... some elements ..*/
}
}
export default Home
And
#### Two.js ####
import Home from './Home'
/** SOME CODE **/
const DrawerOptions = {
initialRouteName: Home.getCurrentDirection(),
contentComponent: CustomDrawerContentComponent,
drawerWidth: 300,
};
However it doesn't work... How to resolve it ? I have already try some solutions as declare the getCurrentDirection as static but nothing.
In addition, it seems to be a specific case because DrawerOptions is not a class. Could you please, add to your response also, how make it if I want to obtain the variable into the class Two.js ?
I meant if Two.js was for example :
##### Two.js #####
class Two extends Component {
var myvariable = Home.getCurrentDirection();
render() {
/***..... some elements ..*/
}
}
Thanks a lot in advance
A recommendable way of accessing the state from a component into another is to use (in this case) the Home component as a parent of Two component. This way you don't have to trigger a function to access the Home's state. On each time when the state of the parent (in this case) component will be updated, the Two component will receive the updated property (direction). If you want to call a function from Two component, you have to pass it a function as a property (changeCurrentDirection) that will call back the function you want to trigger from Home component.
So you would have something like this:
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
direction: "defaultValue"
};
}
changeCurrentDirection() {
this.setState({
direction: "valueChanged"
})
}
render() {
let state = this.state;
return (
<Two
direction={state.direction}
changeCurrentDirection={() => this.changeCurrentDirection.bind(this)}/>
)
}
}
class Two extends React.Component {
render() {
let props = this.props;
return (
<div>
<h3>{props.direction}</h3>
<button onClick={props.changeCurrentDirection()}>Change value</button>
</div>
)
}
}
React.render(<Home/> , document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.0/react.min.js"></script>
<div id="app"></div>
Additional info you can find here.
Also, if you want to have a good management of the state of your components, my advice for you is to use redux. Using this library you can easily connect the component's actions and properties that can further be accessible from other files where you can manage them.

How to render component with ajax in react native?

My code is
const main = () => {
let caption;
AsyncStorage.getItem("XXX", (err, result) => {
caption = <View>...</View>
});
render (
...
{caption}
...
);
}
But I got an error as below.
RawText "" must be wrapped in an explicit <Text> component.
I'm going to assume that, based on your pseudo-code, you understand how to get data from AsyncStorage, that it's not a good idea to be using AsyncStorage inside your render function, and that you don't actually mean ajax but rather local storage.
But the error is showing up because you need to make sure you wrap text inside a <Text> element. If you look at this paragraph it says:
In React Native, we are more strict about it: you must wrap all the text nodes inside of a <Text> component; you cannot have a text node directly under a <View>.
EDIT:
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
data: '',
};
}
componentDidMount() {
AsyncStorage.getItem('XXX', (err, result) => {
// #TODO: You should handle errors too
this.setState({
data: result.text,
});
});
}
render() {
// Returning null will not render anything
// Once the results come in, it will update automatically
if (!this.state.data) return null;
// Raw text must be wrapped in Text
return (
<Text>{this.state.data}</Text>
);
}
}
You can try to stock data in a state and display your component whit a function:
AsyncStorage.getItem("XXX", (err, result) => {
this.setState({result:result})
});
function element(){
if([check if your state is not null])
return(
<View>... {this.state.result} ...</View>
)
}
render (
...
{this.element()}
...
);