S
SolidJS2y ago
Tur

How to send data between different pages using Solid js?

Hello! I need to send user's phone number between 2 different pages. I know I could use a browser's Session Storage to do that but I'm not sure it is a good practice. Is there smth like VueX in vue.js or other ideas?
45 Replies
Tommypop
Tommypop2y ago
You can create a context provider that will allow for you to store that state in a component high in the component tree, and then you can reference that context from any component below it.
Tommypop
Tommypop2y ago
SolidJS
Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.
Tommypop
Tommypop2y ago
Stores and signals can also be created globally and imported into a component. So you can probably just create and export that store from outside that component and then you can import just the store
Tur
Tur2y ago
I tried creating store globally but I failed to get any data to target component
Import Wizard from '../../components/Wizard';
import { loginStore } from '../Login';
function signUp() {
// eslint-disable-next-line no-unused-vars
const [phoneState, setPhoneNumber] = loginStore();
console.log(loginStore());
return (
<Wizard wizardHeader="Header">
<p>
{phoneState.phoneNumber}
<a href="/#">Change</a>
</p>
</Wizard>
);
}
export default signUp;
Import Wizard from '../../components/Wizard';
import { loginStore } from '../Login';
function signUp() {
// eslint-disable-next-line no-unused-vars
const [phoneState, setPhoneNumber] = loginStore();
console.log(loginStore());
return (
<Wizard wizardHeader="Header">
<p>
{phoneState.phoneNumber}
<a href="/#">Change</a>
</p>
</Wizard>
);
}
export default signUp;
import { createStore } from 'solid-js/store';
export function loginStore() {
const [phoneState, setPhoneState] = createStore({ phoneNumber: '' });
return [phoneState, setPhoneState];
}
export function Login() {
//Create a store to hold the state of phone number
// const loginStore = createStore({ phoneNumber: '' });
const [phoneState, setPhoneState] = loginStore();
// const [phoneNumber, setPhoneNumber] = createSignal('');
const handleSubmit = async (event) => {
event.preventDefault();
try {
// Perform form submission logic here, such as sending login information to an API using async/await
const response = await axios.post('/api/phone/check', { phoneNumber: phoneState.phoneNumber });
console.log(response);
} catch (error) {
console.error(error);
}
};
const handlePhoneChange = (event) => {
// setPhoneNumber(event.target.value);
setPhoneState({ phoneNumber: event.target.value });
};
// Do smth ...
}
import { createStore } from 'solid-js/store';
export function loginStore() {
const [phoneState, setPhoneState] = createStore({ phoneNumber: '' });
return [phoneState, setPhoneState];
}
export function Login() {
//Create a store to hold the state of phone number
// const loginStore = createStore({ phoneNumber: '' });
const [phoneState, setPhoneState] = loginStore();
// const [phoneNumber, setPhoneNumber] = createSignal('');
const handleSubmit = async (event) => {
event.preventDefault();
try {
// Perform form submission logic here, such as sending login information to an API using async/await
const response = await axios.post('/api/phone/check', { phoneNumber: phoneState.phoneNumber });
console.log(response);
} catch (error) {
console.error(error);
}
};
const handlePhoneChange = (event) => {
// setPhoneNumber(event.target.value);
setPhoneState({ phoneNumber: event.target.value });
};
// Do smth ...
}
Tommypop
Tommypop2y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Tommypop
Tommypop2y ago
Don't create the state within loginStore because it recreates the phoneState every time it's called
import { createStore } from 'solid-js/store';

export const [phoneState, setPhoneState] = createStore({ phoneNumber: '' });


export function Login() {
const handleSubmit = async (event) => {
event.preventDefault();
try {
// Perform form submission logic here, such as sending login information to an API using async/await
const response = await axios.post('/api/phone/check', { phoneNumber: phoneState.phoneNumber });
console.log(response);
} catch (error) {
console.error(error);
}
};
const handlePhoneChange = (event) => {
// setPhoneNumber(event.target.value);
setPhoneState({ phoneNumber: event.target.value });
};
// Do smth ...
}
import { createStore } from 'solid-js/store';

export const [phoneState, setPhoneState] = createStore({ phoneNumber: '' });


export function Login() {
const handleSubmit = async (event) => {
event.preventDefault();
try {
// Perform form submission logic here, such as sending login information to an API using async/await
const response = await axios.post('/api/phone/check', { phoneNumber: phoneState.phoneNumber });
console.log(response);
} catch (error) {
console.error(error);
}
};
const handlePhoneChange = (event) => {
// setPhoneNumber(event.target.value);
setPhoneState({ phoneNumber: event.target.value });
};
// Do smth ...
}
This should work And then you can simply import the exported variables within your other components Like this:
Tommypop
Tommypop2y ago
Tur
Tur2y ago
And I guess I can just use CreateSignal here
Tommypop
Tommypop2y ago
Yeah If you're only storing the phone number, there's no point wrapping it in a store If you're planning on adding more global state, a context provider might be a better option.
Tur
Tur2y ago
That's not working -- the same result. It's working just on the same page where a signal is created
Tommypop
Tommypop2y ago
Are you able to recreate the issue in a solid playground?
Tommypop
Tommypop2y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Tur
Tur2y ago
Ok. I'll try
Tommypop
Tommypop2y ago
Is there any error message that shows up when you try to access the signals from somewhere else?
Tur
Tur2y ago
Nope
Tommypop
Tommypop2y ago
Can you show me the code for both files?
Tur
Tur2y ago
export const [phoneNumber, setPhoneNumber] = createSignal('');
export function Login() {
//Create a store to hold the state of phone number
const handleSubmit = async (event) => {
event.preventDefault();
try {
// Perform form submission logic here, such as sending login information to an API using async/await
const response = await axios.post('/api/phone/check', { phoneNumber: phoneNumber() });
console.log(response);
} catch (error) {
console.error(error);
}
};
const handlePhoneChange = (event) => {
setPhoneNumber(event.target.value);
};
return (
<div class={styles.background}>
<div class={styles.wizard}>
<a class={styles.logo} href="/">
<img alt="logo" src={logoUrl} />
</a>
<h1>Enter on site</h1>
<form onSubmit={handleSubmit}>
<InputField
inputId="PhoneID"
inputType="tel"
promptMessage="Message"
labelValue="phone number"
textPlaceholder="__ (___) ___-__-__"
onChange={handlePhoneChange}
/>
<div class={styles.btngroup}>
<Button theme="filled" btntype="btn-submit" onClick={handleSubmit}>
Войти
</Button>
<Button href="/sign-up" text="Create account" theme="filled_inactive" />
</div>
</form>
</div>
</div>
);
}
export const [phoneNumber, setPhoneNumber] = createSignal('');
export function Login() {
//Create a store to hold the state of phone number
const handleSubmit = async (event) => {
event.preventDefault();
try {
// Perform form submission logic here, such as sending login information to an API using async/await
const response = await axios.post('/api/phone/check', { phoneNumber: phoneNumber() });
console.log(response);
} catch (error) {
console.error(error);
}
};
const handlePhoneChange = (event) => {
setPhoneNumber(event.target.value);
};
return (
<div class={styles.background}>
<div class={styles.wizard}>
<a class={styles.logo} href="/">
<img alt="logo" src={logoUrl} />
</a>
<h1>Enter on site</h1>
<form onSubmit={handleSubmit}>
<InputField
inputId="PhoneID"
inputType="tel"
promptMessage="Message"
labelValue="phone number"
textPlaceholder="__ (___) ___-__-__"
onChange={handlePhoneChange}
/>
<div class={styles.btngroup}>
<Button theme="filled" btntype="btn-submit" onClick={handleSubmit}>
Войти
</Button>
<Button href="/sign-up" text="Create account" theme="filled_inactive" />
</div>
</form>
</div>
</div>
);
}
import Wizard from '../../components/Wizard';
// eslint-disable-next-line no-unused-vars
import { phoneNumber, setPhoneNumber } from '../Login/Login.jsx';
console.log(phoneNumber);
function signUp() {
return (
<Wizard wizardHeader="User registration">
<p>
{phoneNumber()}
<a href="/#">Change</a>
</p>
</Wizard>
);
}
export default signUp;
}
import Wizard from '../../components/Wizard';
// eslint-disable-next-line no-unused-vars
import { phoneNumber, setPhoneNumber } from '../Login/Login.jsx';
console.log(phoneNumber);
function signUp() {
return (
<Wizard wizardHeader="User registration">
<p>
{phoneNumber()}
<a href="/#">Change</a>
</p>
</Wizard>
);
}
export default signUp;
}
Tommypop
Tommypop2y ago
What's the other file?
Tur
Tur2y ago
Sorry, my mistake console.log shows that phoneNumber is empty
Tommypop
Tommypop2y ago
undefined? or just empty?
Tur
Tur2y ago
empty If I put phoneNumber() But if I write just getter obj I get
readSignal() {
const runningTransition = Transition && Transition.running;
if (this.sources && (!runningTransition && this.state || runningTransition && this.tState)) {
if (!runningTransition…
readSignal() {
const runningTransition = Transition && Transition.running;
if (this.sources && (!runningTransition && this.state || runningTransition && this.tState)) {
if (!runningTransition…
Looks like it comes empty with import
Tommypop
Tommypop2y ago
Maybe try putting the signal in a different file altogether If not, you can always go the context provider route I suspect it's because the Login file reloads at some point So the state within it gets lost You can test it by placing a console.log at the root level in the file, where the signal is created
Tur
Tur2y ago
ok, I'll try. Thank you! I have known a lot today! I'm new bee in Solid.js I used to use Vue and it's completely different
Tommypop
Tommypop2y ago
Yeah, I'm also pretty new to solid Its behaviour can sometimes get inconsistent in my experience
Tur
Tur2y ago
function App() {
return (
<Layout>
<Routes>
<Route path="/" component={Home} />
<Route path="/uslugi/:id" component={People} />
<Route path="/auth" component={Login} />
<Route path="/sign-up" component={SignUp} />
</Routes>
</Layout>
);
}
function App() {
return (
<Layout>
<Routes>
<Route path="/" component={Home} />
<Route path="/uslugi/:id" component={People} />
<Route path="/auth" component={Login} />
<Route path="/sign-up" component={SignUp} />
</Routes>
</Layout>
);
}
May be it reloads because of router?
Tommypop
Tommypop2y ago
It probably gets unmounted You can rectify it by simply declaring the signal outside of the router Like in a new file, for example You could probably pass the signal down as props if you wanted So you could create it in the main file
Tur
Tur2y ago
Yeah! It's quite challenging but interesting.
Tommypop
Tommypop2y ago
Definitely, its model is super different to pretty much anything else No VDOM definitely makes it harder to work with though
Tur
Tur2y ago
Unfortunately I have Solid in production now and I struggle.
function App() {
return (
<Layout>
<Routes>
<Route path="/" component={Home} />
<Route path="/uslugi/:id" component={People} />
<Route path="/auth">
<Route path="/" component={Login} />
<Route path="/sign-up" component={SignUp} />
</Route>
</Routes>
</Layout>
);
}
function App() {
return (
<Layout>
<Routes>
<Route path="/" component={Home} />
<Route path="/uslugi/:id" component={People} />
<Route path="/auth">
<Route path="/" component={Login} />
<Route path="/sign-up" component={SignUp} />
</Route>
</Routes>
</Layout>
);
}
That's how I made it work. I guess the dedicated independent routes drops their state. So when I had rewritten the Router like nested it got worked
Tommypop
Tommypop2y ago
Awesome Do you need to access that phone number anywhere else though? Because then the state would probably be lost in the same way
Tur
Tur2y ago
Yes, that's a right question. It loses the phoneNumber once I reload the page. May be using the context provider solve this problem.
Tommypop
Tommypop2y ago
If you want data to persist upon page reload, you'll need to put the number into local storage You can use a context provider to do that, with an effect on the phonenumber signal that updates localStorage upon change
Tur
Tur2y ago
So I just could use browser's Session storage without using signals at all :)))
Tommypop
Tommypop2y ago
You could But it's generally not a great idea Mostly because localStorage isn't reactive
Tur
Tur2y ago
I just wanted phoneNumber not to be seen out of app's runtime. So I use signals here. I guess I don't need the reactivity in this case. 1. User fill in the phone 2. I check If there is a user with such unique phone 3. If not I inform them and suggest to sign up So there is not the case where the initially typed phone number could be changed somehow
Tommypop
Tommypop2y ago
How are you persisting their login state?
Tur
Tur2y ago
I haven't implemented that feature yet
Tommypop
Tommypop2y ago
You'll definitely need some sort of username and password based login if you want it to be secure or Oauth
Tur
Tur2y ago
That's my first project where I need to implement it I have a backed based on JWT + cookie And It takes Username and Password
Tommypop
Tommypop2y ago
Oh, awesome That's good What's the phone number for?
Tur
Tur2y ago
Phone number is used as username and my boss want it to be confirmed before it will be written into db Not as username to be more accurate -- as login So I have something like pre-signup logic here
Tommypop
Tommypop2y ago
Yeah, a context provider is probably a bit overkill for persisting data between signup and login pages It's definitely worth using for storing user data though Once they're logged in
Tur
Tur2y ago
That's what I 'm thinking about right now😆 But it's was very useful to learn how signals and stores can be used And even Routers
Tommypop
Tommypop2y ago
awesome good luck with your app
Tur
Tur2y ago
Thank you a lot. I'm glad to meet you here. Best wishes to you in your projects!
Want results from more Discord servers?
Add your server