I have been trying for ages to make Sanity work with React Native and It's not working out, read multiple documentations, followed many tutorials but no luck.... What am i doing wrong?
Made a simple recreation here:
https://snack.expo.dev/#spts/smelly-candies
Please let me know what I'm doing wrong, or what I have to do to make it work
There are a few things wrong here, first I'll assume you meant Sanity and not Strapi:
Data isn't loading from Sanity because you need to enable CORS for the expo playground: see more details here
Make sure you set an apiVersion in sanity.js
There were a few issues with your React code which I've updated below, and should work once the CORS issue is resolved.
import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
import sanityClient from './sanity.js'
export default function App() {
const [stuff, setStuff] = useState([]);
useEffect(() => {
async function fetchData() {
const query = '*[_type == "post"] { title, content, emojiType }';
const data = await sanityClient.fetch(query);
setStuff(data)
}
fetchData()
}, [])
return (
<View>
<Text >
Change code in the editor and watch it change on your phone! Save to get a shareable url.
</Text>
<Text>{JSON.stringify(stuff)}</Text>
</View>
);
}
Related
I encounter a strange behavior with pinia in a Vue3 app.
I created a little app with a pinia store using option API.
Here is my main.js with creating the store :
import { createApp } from "vue";
import { createPinia } from "pinia";
// Vue Router
import index from "./router";
// import { useAspergesStore } from "./store/storeAsperges";
import App from "~/App.vue";
import "~/styles/tailwind.css";
import "~/styles/main.scss";
const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
app.use(index);
app.mount("#app");
Here is my store :
import { defineStore } from 'pinia'
import axios from "axios";
export const useAspergesStore = defineStore('asperges', {
state: () => ({
listeCueilleurs: JSON.parse(localStorage.getItem("listeCueilleurs")) || [],
}),
getters: {
...
},
actions: {
...
},
})
And I call the store from my components :
import { useAspergesStore } from '../../../store/storeAsperges.js';
import { mapStores } from 'pinia';
...
computed: {
...mapStores(useAspergesStore),
},
When I start the web page, I can't get the datas from the store, even on a reload. The store is not loaded.
When I open the devTools in chrome, it doesn't show that the store is loaded.
When I click on the vueDevTools, the store loads and the datas appear in the web page.
I get the message in the console :
"🍍 "asperges" store installed 🆕"
It's like starting the vueDevTools triggers the store. And all work fine after that.
If you have any idea of what I'm doing wrong, any help would be appreciated.
Ok I found a solution. I don't know if it's the right one, but it works.
I just tried to call the store from the component in the mounted() hook and now the store loads correctly.
But anyway, I don't know why the store didn't load even if the datas were used in the components...
In Nextjs 13 - experimental app directory, if I wanted to use useState on the root layout/page I must add ‘use client’ to the code, which effectively prevents all nested components from being server components.. how can I work around this so that I can use useState and still have server components. Thanks to any responders.
I don't know if this answers to your question (it's better to add some example code to help users understand your problem)
If you create a Server Component, and in that component you add your Client Component, it works fine. For example
ClientComponent.tsx
"use client";
import {useState} from 'react';
export default function ClientComponent() {
const [count, setCount] = useState(0);
return (
<>
<h1>Client Component</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</>
)
}
ServerComponent.tsx
async function getData(){
const res = await fetch('http://localhost:3000/api/hello');
return await res.json();
}
export default async function ServerComponent() {
const data = await getData()
return (
<>
<h1>Server Component</h1>
<p>{data.name}</p>
</>
)
}
Api hello.ts
export default async function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
Your page
import ClientComponent from "./ClientComponent";
import ServerComponent from "./ServerComponent";
export default function Page() {
return(<>
<ClientComponent/>
<ServerComponent/>
</>
)
}
In this example ServerComponent is rendered on the server, but ClientComponent on the client so it maintain interactivity
Hope this will help
My group and I are currently working on a mobile app using expo-cli and firebase as the backend. One of the requirements is we need to get users' screen time and record how frequently users press certain buttons. According to expo firebase documentation, it only supports limited Firebase Analysis. We were wondering what would be the best way to use Firebase Analytics with Expo to capture screen time and button pressed frequencies.
Screen Tracking
Screen tracking in React Native is different than in a native app since some navigation libraries run inside one Activity/Viewcontroller.
Assuming you are using react-native-navigation, which does have full native navigation support you can handle screen tracking like this.
import analytics from '#react-native-firebase/analytics';
import { Navigation } from 'react-native-navigation';
Navigation.events().registerComponentDidAppearListener(async ({ componentName, componentType }) => {
if (componentType === 'Component') {
await analytics().logScreenView({
screen_name: componentName,
screen_class: componentName,
});
}
});
Look here for the documentation
If you are using react-navigation you can still work around the lack of native screen support by hooking into the events that are provided.
import analytics from '#react-native-firebase/analytics';
import { NavigationContainer } from '#react-navigation/native';
const App = () => {
const routeNameRef = React.useRef();
const navigationRef = React.useRef();
return (
<NavigationContainer
ref={navigationRef}
onReady={() => {
routeNameRef.current = navigationRef.current.getCurrentRoute().name;
}}
onStateChange={async () => {
const previousRouteName = routeNameRef.current;
const currentRouteName = navigationRef.current.getCurrentRoute().name;
if (previousRouteName !== currentRouteName) {
await analytics().logScreenView({
screen_name: currentRouteName,
screen_class: currentRouteName,
});
}
routeNameRef.current = currentRouteName;
}}
>
...
</NavigationContainer>
);
};
export default App;
Here you can find a full example starter app.
Button Press Events
For logging press events there's a lot of documentation on the RNFirebase website.
A simple example to track a custom event that could be an onPress or anything would look like this:
import react, { useEffect } from 'react';
import { View, Button } from 'react-native';
import analytics from '#react-native-firebase/analytics';
function App() {
return (
<View>
<Button
title="Add To Basket"
onPress={async () =>
await analytics().logEvent('onPressAddToBasket', {
id: 3745092,
item: 'Your product name',
description: ['round neck', 'long sleeved'],
size: 'L',
wheneverYouWantToTrack: true,
})
}
/>
</View>
);
}
image of the ERROR
OK so I'm starting a new project and this is the first time that this has happened to me/ I keep getting an error stating ×
TypeError: middleware is not a function i checked dependencies and everything seems fine gone over my code nothing seems wrong please help
I tried deleting the modules and installing them again, I also checked on a passed application I've been doing and since I'm just starting out the code looks identical but that seems to work.
import { createStore, applyMiddleware } from "redux";
import promiseMiddleware from "redux-promise-middleware";
import userReducer from "./ducks/userReducer";
const middleware = applyMiddleware(promiseMiddleware());
const store = createStore(userReducer, middleware);
export default store;
import React, { Component } from "react";
import routes from "./routes";
import { Provider } from "react-redux";
import store from "./redux/store";
class App extends Component {
render() {
return (
<Provider store={store}>
<div className="App">{routes}</div>
</Provider>
);
}
}
export default App;
When you use the function applyMiddleware, the middlewares shouldn't be called as functions.
So instead of:
const middleware = applyMiddleware(promiseMiddleware());
do:
const middleware = applyMiddleware(promiseMiddleware);
See https://redux.js.org/api/applymiddleware#example-custom-logger-middleware for more details.
Is there any way to integrate redux with aws-appsync in react-native?
If there is can you give me hint or clue on how to do it? I'm having a hard time integrating it. Thank you in advance.
I think you should be able to connect your own redux store as is detailed in their documentation. Basically create your own and use connect(mapStateToProps, mapDispatchToProps) from react-redux to connect your components.
const MyComponent = props => <h1>HI!</h1>
const ReduxConnected = connect(mapStateToProps, mapDispatchToProps)(MyComponent)
const GraphQLConnected = graphql(gql`query { hi }`)(ReduxConnected)
And then at the root of your application have
import AWSAppSyncClient from "aws-appsync";
import { Provider as ReduxProvider } from 'react-redux'
import { graphql, ApolloProvider } from 'react-apollo';
import { Rehydrated } from 'aws-appsync-react';
import { createStore } from 'redux'
const client = new AWSAppSyncClient({...})
const store = createStore({...})
const ConnectedApp = () =>
<ApolloProvider client={client}>
<Rehydrated>
<ReduxProvider store={store}>
<App />
</ReduxProvider>
</Rehydrated>
</ApolloProvider>
I haven't had a chance to try this setup but I will soon and will edit with any findings. In the meantime here is a link showing how to build a full RN app with AppSync that uses MobX instead of Redux (https://github.com/dabit3/heard) that may also be a good place to start.