how to use react-big-calendar onRangeChange option - reactjs

enter image description here
i want don't move calendar month so use this code
const FullCalendar = (props) => {
const { calendarInfos, height, dateInfo } = props
const { selectDate } = dateInfo
const localizer = momentLocalizer(moment);
return (
<>
<CalendarCss />
<Calendar
toolbar={false}
popup={false}
localizer={localizer}
culture='ko'
views={['month']}
events={calendarInfos}
defaultDate={new Date(moment(selectDate))}
startAccessor="start"
endAccessor="end"
onRangeChange={(e)=>{console.log(e)}}
style={{
height: height + 'px',
width: '100%',
}}
components={
{
event: (e) =>
(
<FullCalendarEvent
event={e}
/>
)
,
}
}
/>
</>
);
};
but there is an error in this code.
enter image description here
how to use react-big-calendar option onRangeChange

According to the documentation, it depends on the view (sorta).
const onRangChange = (Range: [Date]) => do something
// or, the more likely
const onRangChange = ({start: Date, end: Date}) => do something
Supposed to use the second type for all builtin views, so unsure when that first type would qualify...
If you're trying to restrict it from moving month to month, better option is to use the controlled date prop and do some check to determine wether you set it or not.

Related

How to apply animation in react-native?

I want to add animation to this search bar.
when the user touches the search bar it size decreases and again increases and gets to its default size(like animation in popups)
This is my code
<View style={{flexDirection:'row',alignSelf:'center'}}>
<TextInput
onChangeText={(text) => setSearch(text)}
onFocus={()=>{
setSize('92%');
setInterval(()=>{setSize('95%')},1000)
}}
placeholder="Search"
style={{...styles.searchbox,width:size}}
></TextInput>
</View>
I am currently trying to change width..
Firstly, I suggest you to take a look at RN animated documentation, maybe it will help you to understand better how the animations work.
Also, it depends on what you're having there: a class component or a function component.
If you're using a function component, you could do it like this:
Creating a custom hook, called, let's say useAnimation(), which would look something like this
export const useAnimation = ({ doAnimation, duration, initialValue, finalValue }) => {
const [animation, setAnimation] = useState(new Animated.Value(initialValue))
useEffect(() => {
Animated.spring(animation, {
toValue: doAnimation ? initialValue : finalValue,
duration,
bounciness: 8,
useNativeDriver: false
}).start();
}, [doAnimation]);
return animation
}
As it is said in the documentation, you could animate only Animated components, and for example if you want to have an animated View, the tag will be <Animated.View> {...} </Animated.View, but for the <TextInput> we have to create the animated component:
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput)
and combining the first 2 steps
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput)
const [collapsed, setCollapsed] = useState(true)
const animation = useAnimation({ doAnimation: collapsed, duration: 300, initialValue: 20, finalValue: 200 });
const onFocusText = () => setWidth(false)
return (
<AnimatedTextInput
onFocus={onFocusText}
placeholder={"Search something"}
style={{width: animation, height: 50, borderColor: 'gray', borderWidth: 1, borderRadius: 4, padding: 10}}
/>
)
Also, if you're having a class component, you could have a method which will start the animation (but don't forget about the step 2 which is essential)
private size: Animated.Value = new Animated.Value(COLLAPSED_VALUE)
get resizeInputWidth(): Animated.CompositeAnimation {
return Animated.timing(this.size, {
toValue: EXPANDED_VALUE,
duration: 500,
})
}
startAnimation = () => this.resizeInputWidth.start()
<AnimatedTextInput
onFocus={this.startAnimation}
style={{ width: this.size }}
/>

TextInput /Input element looses focus on key press

I'm currently developing an application using React Native.
This trial app has a component that has a TextInput and two buttons (ADD and DELETE).
When I press the ADD Button, a new component appears. If I press the DELETE Button that the same component disappears.
The screen is like the photo bellow:
I control the TextInput with the index which is the same number as the index of the component.
My question is: why can't I enter some text as usual in this code?
I have to focus the cursor every time I enter 1 word.
I lose a flashing vertical bar(I check in the photo below) in the input area every time I press a key.
How can I resolve this problem?
And, I want to control the inputted value from TextInput with array[] not object{} because in case of an array is easier to delete a component sliding index and value like an explanation below:
I have no idea to control index and value with an, object and it's complicated for my skill now, but if there are some nice ways to resolve using object, I hope to know it.
Here is the code:
import React, { useState } from "react";
import { View, Text, Button, TextInput, StyleSheet } from "react-native";
function Item({ number, handleInput, handleAdd, handleDelete, index }) {
return (
<View style={styles.list}>
<Text>{index}</Text>
<TextInput
style={{ borderWidth: 1 }}
value={number[index]}
onChange={(e) => {
handleInput(index, e.nativeEvent.text);
}}
></TextInput>
<Button
title="ADD"
onPress={() => {
handleAdd();
}}
/>
<Button
title="DELETE"
onPress={() => {
handleDelete(index);
}}
/>
</View>
);
}
export default function TestStateArray() {
const [count, setCount] = useState(1);
const [number, setNumber] = useState([]);
function handleAdd() {
setCount((v) => v + 1);
}
function handleDelete(index) {
setCount((v) => v - 1);
setNumber((v) => {
const ret = v.slice();
ret.splice(index, 1);
return ret;
});
}
function handleInput(index, text) {
setNumber((v) => {
const ret = v.slice();
ret[index] = text;
return ret;
});
}
return (
<View>
{Array.from({ length: count }, (_, i) => (
<Item
number={number}
handleInput={handleInput}
handleAdd={handleAdd}
handleDelete={handleDelete}
key={i + "-" + number}
index={i}
/>
))}
</View>
);
}
const styles = StyleSheet.create({
list: {
margin: 10,
padding: 10,
backgroundColor: "#ddd",
},
});
After I have some answer and some comment, I tried changing the code like bellow, but it still has the same problem...
// onChange={(e) => {
// handleInput(index, e.nativeEvent.text);
onChangeText={(text) => {
handleInput(index, text);
}}
node : 12.18.3
react native : 4.10.1
expo : 3.22.3
The above issue occurred because your handle change function is wrong.
Please change...
const [number, setNumber] = useState({}); // change array to Object in useState.
Replace your handler with below function:
function handleInput(index, text) {
setNumber({ ...number, index: text });
}
React Native has onChangeText event on TextInput component can you try that one?

React component won't take onChange event

Obligatory "new to react" paragraph here. I have this rating component I got from material-ui and i'm trying to send the value to a database.
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Rating from '#material-ui/lab/Rating';
import Box from '#material-ui/core/Box';
const labels = {
0.5: 'Worst of the Worst',
1: 'Bad',
1.5: 'Poor',
2: 'Passable',
2.5: 'Ok',
3: 'Good',
3.5: 'Damn Good',
4: 'Great',
4.5: 'Love',
5: 'Perfection',
};
const useStyles = makeStyles({
root: {
width: 200,
display: 'flex',
alignItems: 'center',
},
});
export default function HoverRating(props) {
const [value, setValue] = React.useState(2);
const [hover, setHover] = React.useState(-1);
const classes = useStyles();
const onRatingChange = (event) => {
console.log(event.target.value)
props.reduxDispatch ({ type: "RATING_CHANGE", value: event.target.value
})
}
return (
<div className={classes.root}>
<Rating
name="hover-feedback"
value={value}
defaultValue={0}
precision={0.5}
size="large"
onChange={(event, newValue) => {
setValue(newValue);
console.log("your newValue is " + newValue)
}}
onChangeActive={(event, newHover) => {
setHover(newHover);
}}
{ onRatingChange }
/>
<br/>
{value !== null && <Box ml={2}>{labels[hover !== -1 ? hover : value]}</Box>}
</div>
);
}
It doesn't like something about my onRatingChange function. I've moved it all over the place and it's still throwing errors. I just really don't understand the issue. I'm mostly getting-
"./src/components/Rating.js
Line 54:11: Parsing error: Unexpected token, expected "..."
I've been at this for hours and I salvation.
Change your code from:
{ onRatingChange }
to:
onRatingChange={onRatingChange}
and change your file extension from .js to .jsx because you are using the JSX syntax
First, you appear the be storing the rating in two places: in your local state (with React.useState), and from the looks of your onRatingChange function, in a Redux store somewhere. It would be a good idea to pick one, and use that.
As for the direct answer to your question, your syntax is wrong. You're writing your Rating component in the following way:
<Rating
// ...
onChange={(event, newValue) => {
setValue(newValue);
console.log("your newValue is " + newValue)
}}
// ...
{ onRatingChange }
/>
The Rating component expects an onChange prop. I assume you want your onRatingChange function to be called when the rating changes. As such, you'd write:
<Rating
// ...
onChange={onRatingChange}
/>
The complication here though is that you're trying to register two different handlers for the rating change event. The bottom line is, decide on one, and then pass that as a callback function to the onChange prop.

Show loading state but also show previous results in React Concurrent gives a warning

UPDATE: Ok, it I misunderstood useDeferredValue, I thought it was more like a debounced value but it's not, you can define the timeout to be the time the old results will be shown.
So
const search = useDeferredValue(value, { timeoutMs: 10000 })
Gave me the desired effect, only it still show the warning right know.
Original
I want to have a search with the results below it, the search result should filter immediately based on the input of the text field. Then the query should be done debounced and the old results should show also when it takes less than e.g. 3000 m.s.
I'm working with the new concurrent mode in React and Relay experimental. I used the new useDeferredValue, documented on this page: https://reactjs.org/docs/concurrent-mode-reference.html#usetransition
But I got this warning:
Warning: Asynchronous triggered a user-blocking update that suspended.
The fix is to split the update into multiple parts: a user-blocking update to provide immediate feedback, and another update that triggers the bulk of the changes.
Refer to the documentation for useTransition to learn how to implement this pattern
I don't get this since it works but it still gives me a warning.
My code:
import React, {
Suspense,
useState,
// #ts-ignore - useDeferredValue does not exist yet in types
useDeferredValue,
// #ts-ignore - useDeferredValue does not exist yet in types
// useTransition,
useCallback,
ChangeEvent,
} from 'react'
import TextField from '#material-ui/core/TextField'
import LinearProgress from '#material-ui/core/LinearProgress'
import { graphql } from 'babel-plugin-relay/macro'
import { useLazyLoadQuery } from 'react-relay/hooks'
import {
FlowBlockFinderQuery,
FlowBlockFinderQueryResponse,
} from '../__generated__/FlowBlockFinderQuery.graphql'
import ErrorBoundaryWithRetry from '../helpers/ErrorBoundaryWithRetry'
interface RenderFuncProps {
search: string
filterSearch: string
}
function QueryResults({ search, filterSearch }: RenderFuncProps) {
const { blocks }: FlowBlockFinderQueryResponse = useLazyLoadQuery<
FlowBlockFinderQuery
>(
graphql`
query FlowBlockFinderQuery($search: String) {
blocks(search: $search) {
id
title
description
slug
blockType
}
}
`,
{ search },
{ fetchPolicy: 'store-or-network' }
)
return (
<div>
{blocks
.filter(
block =>
!filterSearch ||
block.title.toLowerCase().includes(filterSearch.toLowerCase())
)
.map(block => (
<div key={block.id} style={{ fontSize: 19 }}>
{block.title}
</div>
))}
</div>
)
}
function Results({ search, filterSearch }: RenderFuncProps) {
return (
<>
Zoekterm: {filterSearch}
<ErrorBoundaryWithRetry
fallback={({ error }) => <div>Er is iets foutgegaan</div>}
>
<Suspense fallback={<LinearProgress />}>
<QueryResults search={search} filterSearch={filterSearch} />
</Suspense>
</ErrorBoundaryWithRetry>
</>
)
}
export default function Asynchronous() {
const [value, setValue] = useState('')
// const [search, setSearch] = useState('')
const search = useDeferredValue(value, { timeoutMs: 3000 })
// const [startTransition, isPending] = useTransition(SUSPENSE_CONFIG)
const onInputChange = useCallback(
(event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
// startTransition(() => {
setValue(event.currentTarget.value)
// })
},
[setValue]
)
return (
<div style={{ display: 'flex', flexDirection: 'column' }}>
<TextField
label="Nieuw of bestaand blok"
fullWidth
variant="outlined"
value={value}
onChange={onInputChange}
/>
<br />
<Results search={search} filterSearch={value} />
</div>
)
}
React docs "if some state update causes a component to suspend, that state update should be wrapped in a transition". You have to make the async request suspense compatible and fetch the query in useTransition.
Here is an example from react docs
function handleChange(e) {
const value = e.target.value;
// Outside the transition (urgent)
setQuery(value);
startTransition(() => {
// Inside the transition (may be delayed)
setResource(fetchTranslation(value));
});
}
And the link to code sandbox

how to get selected dates in react calendar?

I downloaded react-native-material-calandarview inside my project.
They just give some piece of code to get calendar. https://github.com/NuclleaR/react-native-material-calendarview.
I just selected datesSelection={'range'}, but I dont know where I get the selected dates. If datesSelection={'single'} it return date in
onDateChange={data => {
console.log(data.date);//date selected
}}
More code:
render() {
return (
<Calendar
width={(Dimensions.get('window').width)-32}
height={280}
tileHeight={35}
style={{alignSelf: 'center'}}
topbarVisible={true}
datesSelection={'range'}
firstDayOfWeek="monday"
showOtherDates="none"
currentDate={this.state.today}
selectedDates={this.state.dates}
eventsDates={[]}
eventsColor="#9C27B0"
onDateChange={data => {
//alert(sel_date);
console.log(this.state.data);
}}
onMonthChange={month => {
//alert(month)
console.log(month);
}}
/>
);
}
So the onChange will show you the date the user selects it's up to you to make a function to store these in redux/local state. Same for a range the onChange will return you that range in the argument you're passing to it
So what you can do is
In HTML:
onDateChange={this.onChange}
Component method:
onChange = (date) => { this.setState({ selectedDate: date }) };

Resources