How to upgrade from V1 to V2? Need full examples - react-select

I don't see any samples showing before and after view of the code for going from v1 to v2.
We have a wrapper for react-select in our file Select.jsx that in V1 contains
import React from 'react';
import ReactSelect from 'react-select';
import css from 'react-css-modules';
import globalStyles from '../../../node_modules/react-select/dist/react-select.css';
import styles from './Select.css';
/**
* Select component
* How do we style this?
*/
const Select = (props) => {
const onChange = values => {
props.multi ? props.onChange(_.map(values, obj => obj.value)) : props.onChange(values.value)
};
return <ReactSelect
multi={props.multi}
value={props.value}
options={props.options}
disabled={props.disabled}
placeholder={props.placeholder}
clearable={props.clearable}
className={`${props.type} ${props.kind}`}
tabSelectsValue={props.tabSelectsValue}
searchable={props.searchable}
optionComponent={props.optionComponent}
valueComponent={props.valueComponent}
onChange={onChange} />;
}
export default css(Select, styles);
A preliminary stab in the dark attempt to convert it (but not styling) to react-select V2 looks like:
import React from 'react';
import ReactSelect, { components } from 'react-select';
import css from 'react-css-modules';
import styles from './Select.css';
/**
* Select component
* How do we style this?
*/
const Select = (props) => {
const onChange = values => {
props.multi ? props.onChange(_.map(values, obj => obj.value)) : props.onChange(values.value)
};
const Options = (props) => {
return (
<components.Option {...props.optionComponent}/>
/*<components.ValueContainer {...props.valueComponent}/>*/
);
};
const MultiValueContainer = (props) => {
return (
<components.MultiValueContainer {...props.valueComponent}/>
);
};
return <ReactSelect
isMulti={props.multi}
value={props.value}
options={props.options}
isDisabled={props.disabled}
placeholder={props.placeholder}
isClearable={props.clearable}
className={`${props.type} ${props.kind}`}
tabSelectsValue={props.tabSelectsValue}
isSearchable={props.searchable}
components={{ Options, MultiValueContainer }}
onChange={onChange} />;
}
export default css(Select, styles);
A sample use in V1 looks like:

Related

RTK query function is undefined in react native

I'm using RTK query to fetch data from the endpoint, setup the folder structure like this
src (root)
features/api/apiSlice.js
screens/ChatScreen.js
I have setup apiSlice.js like this
import {createApi, fetchBaseQuery} from '#reduxjs/toolkit/query/react';
export const apiSlice = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({baseUrl: 'https://api.covid19api.com'}),
endpoints: builder => ({
getEmojiPoints: builder.query({
query: () => '/countries',
}),
}),
});
export const {useGetEmojiPoints} = apiSlice;
then imported the useGetEmojiPoints hook in functional component like this
import {useGetEmojiPoints} from '../features/api/apiSlice';
const {
data: emojiPoints,
isLoading,
isSuccess,
isError,
error,
} = useGetEmojiPoints(); // getting this undefined (not a function)
Setup App.js like this
import React from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
useColorScheme,
Text,
StyleSheet,
} from 'react-native';
import ChartScreen from './src/screens/ChartScreen';
import {ApiProvider} from '#reduxjs/toolkit/query/react';
import {apiSlice} from './src/features/api/apiSlice';
const AppWrapper = () => {
return (
<ApiProvider api={apiSlice}>
<App />
</ApiProvider>
);
};
const App = () => {
const isDarkMode = useColorScheme() === 'dark';
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<ScrollView>
<ChartScreen />
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {flex: 1, backgroundColor: '#fff'},
});
export default AppWrapper;
Whats wrong why its giving me undefined for query hook?
It's useGetEmojiPointsQuery, not useGetEmojiPoints.

Check the render method of `InstanceImage` while testing using testing-library/react-native

I am trying to test a functional component with Redux using testing-library/react-native.
//InstanceImage.component.js
export default InstanceImage = (props) => {
// <props init, code reduced >
const { deviceId, instanceId } = DeviceUtils.parseDeviceInstanceId(deviceInstanceId)
const deviceMap = useSelector(state => {
return CommonUtils.returnDefaultOnUndefined((state) => {
return state.deviceReducer.deviceMap
}, state, {})
})
const device = deviceMap[deviceId]
const instanceDetail = device.reported.instances[instanceId]
if (device.desired.instances[instanceId] !== undefined) {
return (
<View
height={height}
width={width}
>
<ActivityIndicator
testID={testID}
size={loadingIconSize}
color={fill}
/>
</View>
)
}
const CardImage = ImageUtils[instanceDetail.instanceImage] === undefined ? ImageUtils.custom : ImageUtils[instanceDetail.instanceImage]
return (
<CardImage
testID={testID}
height={height}
width={width}
fill={fill}
style={style}
/>
)
}
And the test file is
//InstanceImage.component.test.js
import React from 'react'
import { StyleSheet } from 'react-native';
import { color } from '../../../../src/utils/Color.utils';
import ConstantsUtils from '../../../../src/utils/Constants.utils';
import { default as Helper } from '../../../helpers/redux/device/UpdateDeviceInstanceIfLatestHelper';
import InstanceImage from '../../../../src/components/Switches/InstanceImage.component';
import { Provider } from 'react-redux';
import { render } from '#testing-library/react-native';
import configureMockStore from "redux-mock-store";
import TestConstants from '../../../../e2e/TestConstants';
const mockStore = configureMockStore();
const store = mockStore({
deviceReducer: {
deviceMap: Helper.getDeviceMap()
}
});
const currentState = ConstantsUtils.constant.OFF
const styles = StyleSheet.create({
// styles init
})
const props = {
//props init
}
describe('Render InstanceImage', () => {
it('InstanceImage renders correctly with values from props and Redux', () => {
const rendered = render(<Provider store={store}>
<InstanceImage {...props}/>
</Provider>)
const testComponent = rendered.getByTestId(TestConstants.icons.INSTANCE_IMAGE)
});
})
And when I run the test file it gives the following error
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of `InstanceImage`.
The component runs correctly when the app is run and there aren't any crashes. Still, this error occurs while performing tests.I am new to creating test cases for react native app so not able to debug this issue.
Found the error, the CardImage returns a custom svg image which was causing the issue. I used the jest-svg-transformer and it solved the issue.
Reference: https://stackoverflow.com/a/63042067/4795837

I got this unexpected error in React-Native

Error: Element type is invalid: expected a string (for built-in components) or
a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of App.
Here is the code of App.js
import React, { useState } from 'react';
import { StyleSheet, View } from 'react-native';
import * as Fonts from 'expo-font';
import { AppLoading } from 'expo-app-loading';
import Header from './components/Header';
import StartGameScreen from './screens/StartGameScreen';
import GameScreen from './screens/GameScreen';
import GameOverScreen from './screens/GameOverScreen';
const fetchFonts = () => {
return Fonts.loadAsync({
'open-sans': require('./assets/fonts/OpenSans-Regular.ttf'),
'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf')
});
};
export default function App() {
const [userNumber, setUserNumber] = useState();
const [guessRounds, setGuessRounds] = useState(0);
const [dataLoaded, setDataLoaded] = useState(false);
if (!dataLoaded) {
return <AppLoading
startAsync={fetchFonts}
onFinish={() => setDataLoaded(true)}
onError={(err) => console.log(err)}
/>
}
const configureNewGameHandler = () => {
setGuessRounds(0);
setUserNumber(null);
};
const startGameHandler = selectedNumber => {
setUserNumber(selectedNumber);
};
const gameOverHandler = numOfRounds => {
setGuessRounds(numOfRounds);
};
let content = <StartGameScreen onStartGame={startGameHandler} />;
if (userNumber && guessRounds <= 0) {
content = (
<GameScreen userChoice={userNumber} onGameOver={gameOverHandler} />
);
} else if (guessRounds > 0) {
content = (
<GameOverScreen
roundsNumber={guessRounds}
userNumber={userNumber}
onRestart={configureNewGameHandler}
/>
);
}
return (
<View style={styles.screen}>
<Header title="Guess a Number" />
{content}
</View>
);
}
const styles = StyleSheet.create({
screen: {
flex: 1
}
});
Most likely you forgot to "export default" in one of these components
import Header from './components/Header';
import StartGameScreen from './screens/StartGameScreen';
import GameScreen from './screens/GameScreen';
import GameOverScreen from './screens/GameOverScreen';
If you are just "export"ing without "default", then use {} while importing

React Native Date Range

import React, {useState} from "react";
import { StyleSheet, View, Text } from "react-native";
import { globalStyles } from "../styles/global";
import {Calendar, CalendarList, Agenda} from 'react-native-calendars';
import {LocaleConfig} from 'react-native-calendars';
import moment from "moment";
import DateRangePicker from "react-native-daterange-picker";
export default function About(){
const [endDate, setendDate] = useState(null)
const [startDate, setstartDate] = useState(null)
const [displayedDate, setdisplayedDate] = useState(moment())
state = {
endDate: null,
startDate: null,
displayedDate: moment()
};
const handleSubmit = (props) => {
console.log(props);
setendDate(props.endDate);
setstartDate(props.startDate);
setdisplayedDate(props.displayedDate);
// console.log(props.startDate);
// console.log(props.displayedDate);
}
return(
<View style={globalStyles.container}>
<DateRangePicker
onChange={ handleSubmit }
endDate={endDate}
startDate={startDate}
displayedDate={displayedDate}
range>
<Text>Click me!</Text>
</DateRangePicker>
</View>
)
}
1.not able to select date range.
2. undefined is not an object (evaluating displayedDate.format)
3. Using function component but most of the solutions are available with class component
You can call handleSubmit as follows
onChang={() => handleSubmit()}
And props param is needless in function prototype
const handleSubmit = (props) => {}
Because props is already declared and you don't need to set it as parameter.
If you want to use it as parameter then you should change like this
onChange={() => handleSubmit(props)}
Hope this helps you.
You can change your handleSubmit() function like this
const handleSubmit = (props) => {
if (props.startDate != undefined) {
setStartDate(props.startDate);
}
if (props.displayedDate != undefined) {
setDisplayedDate(props.displayedDate);
}
if (props.endDate != undefined) {
setEndDate(props.endDate);
}
}
Source: issues#15

Change theme like Fabric Web ( Default / Dark)

In the documentation page of fabric, now each example component have a change theme funcionality
ie: example
enter image description here
How can I achive this funcionality. I have 2 themes (created in) and I want to switch betwen thems
Here is my preferred way, using React Context.
import React from 'react';
import { Fabric, Customizer } from '#fluentui/react';
import { useLocalStorage } from 'react-use';
// Setup Theme Context and create hooks
import {
DefaultCustomizations,
DarkCustomizations
} from '#uifabric/theme-samples';
export const ThemeList = {
light: DefaultCustomizations,
dark: DarkCustomizations
};
export const ThemeContext = React.createContext({
theme: 'light',
changeTheme: name => {}
});
const ThemeWrapper = ({ children }) => {
return (
<ThemeContext.Consumer>
{({ theme }) => (
<Customizer {...ThemeList[theme]}>
<Fabric>{children}</Fabric>
</Customizer>
)}
</ThemeContext.Consumer>
);
};
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useLocalStorage('theme', 'dark');
const changeTheme = name => ThemeList[name] && setTheme(name);
const value = { theme, changeTheme };
return (
<ThemeContext.Provider value={value}>
<ThemeWrapper>{children}</ThemeWrapper>
</ThemeContext.Provider>
);
};
export const useTheme = () => React.useContext(ThemeContext);
// Now demo how to use it
export function App() {
const { theme, changeTheme } = useTheme();
return (
<button onClick={() => changeTheme('dark')}>
Switch to dark
</button>
);
}
import ReactDOM from 'react-dom';
ReactDOM.render(
<ThemeProvider>
<App />
</ThemeProvider>,
document.getElementById('root')
);
Note to moderator: Sorry that this answer was originally a duplicate. I deleted the duplicate.