addEventListener for a specific element - events

I have 2 components routes (Accueil & Apropos):
<Route path='/' element={<Accueil />} />
<Route path='/Apropos' element={<Apropos />} />
I used a scroll eventlistener in the component Accueil as:
useEffect(() => {
const handleScroll = () => {
console.log(document.getElementById('presentation').offsetTop)
}
window.addEventListener("scroll", handleScroll)
return () => { window.removeEventListener("scroll", handleScroll)}
}, [])
but I have a problem, when I switch to the other component, the eventlistener still used and shows that document.getElementById('presentation').offsetTop is null.
How can I use an eventlistener just for my component Accueil ?

Related

react hook, validate Form with reduxForm

I Have external component managing my input Field and throws an error if no input is made.
On submit of form previously with class component along with reduxForm effect, this would throw an error of missing input, am wondering how to achieve this with hooks since submission passes whether i have input or Not.
import ConstructField from '../components.render';
const ActivitiesForm = () => {
const handleSubmit_ = () => {
console.log({ activityName });
};
const [activityName, setActivityName] = useState(null);
const handleInputName = (e) => setActivityName(e.target.value);
const { items } = useSelector((state) => ({
items: state.items,
}));
const { register, handleSubmit, errors, control } = useForm();
return (
<div>
<Form onSubmit={handleSubmit(handleSubmit_)} className='ui form'>
<Form.Group widths='equal'>
<Field
component={ConstructField('input')}
onChange={handleInputName}
label='Activity Name'
name='activityName'
placeholder='Activity Name'
validate={required}
/>
</Form.Group>
<br />
<Form.Group inline>
<Button.Group>
<Button primary>Save</Button>
<Button.Or />
<Button positive onClick={goBackButton}>
Go Back
</Button>
</Button.Group>
</Form.Group>
</Form>
</div>
);
};
const required = (value) => (value ? undefined : 'this field is required');
const activityform = reduxForm({
form: 'activityform',
enableReinitialize: true,
})(ActivitiesForm);
export default activityform;

React Native Stack Navigator passing props

I want to pass some props (value) to another page and I'm using stackNavigator
App.js:
import Insert from "./components/pages/Insert";
import ViewData from "./components/pages/ViewData";
const Stack = createStackNavigator();
NavigationContainer>
<Stack.Navigator headerMode={false}>
<Stack.Screen name="Insert Your data" component={Insert} />
<Stack.Screen name="ViewData" component={ViewData} />
</Stack.Navigator>
</NavigationContainer>
Insert.js
const Insert = ({ props, navigation: { navigate } }) => {
const [enteredName, setEnteredName] = useState();
const [enteredSurname, setEnteredSurname] = useState();
const sendValues = (enteredName, enteredSurname) => {
setEnteredName(enteredName);
setEnteredSurname(enteredSurname);
navigate("ViewData", {
name: enteredSurname,
surname: enteredSurname
});
};
...
<View>
<Button
title="Submit"
onPress={() => sendValues(enteredName, enteredSurname)}
/>
ViewData.js
const ViewData = ({props, navigation: { goBack } }) => {
let name = enteredName;
console.log(name); /// I always get undefined
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Here {name}</Text>
<Button onPress={() => goBack()} title="Edit Data" />
</View>
);
};
When I Submit I'm always getting undefined into the console.
For sure I'm mistaking somewhere.
Any idea?
Thanks!!
Refer to https://reactnavigation.org/docs/hello-react-navigation/#passing-additional-props
Use a render callback for the screen instead of specifying a component
prop:
<Stack.Screen name="Home">
{props => <HomeScreen {...props} extraData={someData} />}
</Stack.Screen>
You can change like this
import Insert from "./components/pages/Insert";
import ViewData from "./components/pages/ViewData";
const Stack = createStackNavigator();
<NavigationContainer>
<Stack.Navigator headerMode={false}>
<Stack.Screen name="Insert Your data">
{props => (<Insert {...props} extraData={data}/>)}
<Stack.Screen name="ViewData" component={ViewData} />
</Stack.Navigator>
</NavigationContainer>
Reading your code it seems that you want to pass some params to the render component when navigate.
Refer to https://reactnavigation.org/docs/route-prop , the params from
navigation.navigate(routeName, params)
are passed to the screen render component as propriety of the route object. So in your case it should work:
let name = props.route.params.name;

react-router-dom v4 link to nested route too much recursion

Currently whenever I try to link to a nested route that renders a new element, I get the too much recursion error. For obvious reasons it keeps rerendering this component. Where does one put a nested route so it doesnt get rendered over and over again?
redirectAddSurvey(){
this.props.addSurvey("Titel Survey", "Survey beschrijving"); this.props.history.push(`/survey/${this.props.match.params.action}`);
}
render() {
return (
<div id="newSurveyButton">
<RaisedButton containerElement={ <Link to={`${this.props.match.url}/new`} />} label="Add new Survey" onClick={() => this.redirectAddSurvey()}></RaisedButton>
<Route path={`${this.props.match.url}/:action`} render={props => <Survey title="Helloworld" desc="HelloDesc" {...props} />} />
</div>
);
}
}
// Get apps state and pass it as props to SurveyList
// > whenever state changes, the SurveyList will automatically re-render
function mapStateToProps(state) {
return {
surveys: state.surveys,
};
}
Updated:
render() {
return (
<div id="newSurveyButton">
<RaisedButton label="Add new Survey" onClick={() => this.redirectAddSurvey()}></RaisedButton>
<Link to={`${this.props.match.url}/new`} />
<Route path={`survey/:action`} render={props => <Survey title="Helloworld" desc="HelloDesc" {...props} />} />
</div>
);
}

Admin on Rest onClick being called on render and not on click

The issue I am having is I have a button:
const LogActions = ({ resource, filters, displayedFilters, filterValues, basePath, showFilter, refresh, record }) => (
<CardActions style={cardActionStyle}>
<RaisedButton primary label="Cancel" onClick={HandleClick(record["id"])} />/>
</CardActions>
);
This button is used in a List like so:
export const LogList = (props) => (
<List {...props} perPage={100} title="Logs and Reports" filters={< FileFilter/>}>
<Datagrid>
<TextField source="inputfile" label="Input File" />
<TextField source="cycle" label="Cycle" />
<TextField source="job" label="Job" />
<TextField source="name" label="File Name" />
<ShowButton/>
<LogActions/>
</Datagrid>
</List>
);
This is the HandleClick:
const HandleClick = (id) => {
fetch(`controller_service/archivedfiles/${id}`, { method: 'GET', body:{} })
.then(() => {
// do stuff
})
.catch((e) => {
console.error(e);
//error
});
}
Okay so my problem is that whenever I go to this page, it will create the datagrid, but while the button is being rendered it calls HandleClick which then fetches that data before I even click on the button, and when I click on the button nothing happens. Can someone explain what I am doing wrong?
As wesley6j said, the function gets called when you assign it with parameters.
A way to avoid this is to use .bind(this,params) or wrap your HandleClick in another function like this:
onClick={() => HandleClick(record["id"])}

React-Router with child in Go how does it work?

I'm trying to use react-router with a server in Go.
I did some tests but I can not do what I want.
My react components :
var App = React.createClass({
render: function(){
return (
<div>
<h2>App</h2>
<li><Link to="/page1">Page 1</Link></li>
<li><Link to="/page2">Page 2</Link></li>
</div>
)
}
})
var Page1 = React.createClass({
render: function(){
return (
<div>
<h2>Page 1</h2>
<li><Link to="/page2">Page 2</Link></li>
</div>
)
}
})
var Page2 = React.createClass({
render: function(){
return (
<div>
<h2>Page 2</h2>
<li><Link to="/page1">Page 1</Link></li>
</div>
)
}
})
My react routing :
ReactDOM.render((<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="page1" component={Page1} />
<Route path="page2" component={Page2} />
</Route>
</Router>), document.getElementById('app'))
my go server :
func Render(c web.C, w http.ResponseWriter, r *http.Request) {
RenderHTMLPage(w, "index.html")
}
func main() {
goji.Get("/page1", Render)
goji.Get("/page2", Render)
goji.Get("/", Render)
goji.Serve()
}
My problem is when i click on Link in 'App' Component, for example :
<li><Link to="/page1">Page 1</Link></li>
url changes like that
http://localhost:8000/page1
But actual component is already App and not Page1, so url changes but not component.
And if i load directly url, i have the same result.
Does anyone help me ?
Thank's :)
This isn't a go question, but a react question, you need to render the App component's children in order for the other two components to display, a la this code snippet taken from the docs for React Router (https://github.com/reactjs/react-router/blob/master/docs/API.md#props-2):
const routes = (
<Route component={App}>
<Route path="groups" component={Groups} />
<Route path="users" component={Users} />
</Route>
)
class App extends React.Component {
render () {
return (
<div>
{/* this will be either <Users> or <Groups> */}
{this.props.children}
</div>
)
}
}

Resources