作为一名熟悉ReactJS的软件工程师,如果您能够将熟悉的概念映射到新环境中,那么学习Swift和SwiftUI将是一个平稳的过渡。在本指南中,我们将了解常见的ReactJS模式如何转化为Swift和SwiftUI。
请注意,下面的示例旨在使用简短的代码片段来突出一般概念。
我建议您从GitHub下载 Playground,以便尝试和使用这些示例。
启动一个新的React项目有很多种方法,其中一种方法是使用create-react-app:
npx create-react-app my-app
cd my-app
npm start
在Swift中,您使用Xcode创建一个新的SwiftUI项目:
打开 Xcode
选择“Create a new Xcode project”
选择iOS(或macOS或多平台)后,选择 “App”,并在 “interface” 选项中选择SwiftUI。
组件是应用程序 UI 的构建模块。
在React中,组件通常是返回一些JSX的函数。
const Greeting = () => <h1>Hello, world!</h1>;
在SwiftUI中,组件被称为Views(视图)。您可以将它们定义为符合 View 协议的 structures(结构)。
struct Greeting: View {
var body: some View {
Text("Hello, world!")
}
}
处理用户输入是任何应用程序的常见模式。
ReactJS
在 React 中,您可能会创建一个输入字段,并使用 useState
钩子来跟踪其值。
const InputComponent = () => {
const [inputValue, setInputValue] = useState("");
const handleChange = event => setInputValue(event.target.value);
return ;
};
SwiftUI
SwiftUI简化了这一过程。通过使用 @State 属性包装器并将其绑定到input,SwiftUI 将为您处理同步。
struct InputView: View {
@State private var inputValue = ""
var body: some View {
TextField("Enter text", text: $inputValue)
.padding()
}
}
状态对于响应式用户界面是必不可少的。
ReactJS
在React中,我们经常使用 useState
钩子来管理组件级状态。
const Counter = () => {
const [count, setCount] = useState(0);
return (
);
};
SwiftUI
类似地,在SwiftUI中,我们使用 @State
属性包装器来跟踪视图中的本地状态。
struct CounterView: View {
@State private var count = 0
var body: some View {
Button("Clicked \(count) times") {
count += 1
}
.padding()
}
}
在父子通信中,将函数作为 props 传递是很常见的。
ReactJS
在React中,你可以通过子组件可以调用的 props 将函数传递给子组件。
const Parent = () => {
const handleAction = () => console.log("Action handled");
return <Child onAction={handleAction} />;
};
const Child = ({ onAction }) => <button onClick={onAction}>Do Action</button>;
SwiftUI
在SwiftUI中,通过将闭包传递给子视图也可以实现同样的效果。
struct ParentView: View {
var body: some View {
ChildView(onAction: { print("Action handled") })
}
}
struct ChildView: View {
let onAction: () -> Void
var body: some View {
Button("Do Action", action: onAction)
}
}
ReactJS (使用 Context):
在React中,Context API是共享状态和将状态传递到组件树深处的常用选择,而无需手动传递props。
const AppContext = createContext();
const Parent = () => (
);
const Child = () => {
const context = useContext(AppContext);
return {context.message};
};
SwiftUI (使用 EnvironmentObject):
SwiftUI提供EnvironmentObject,允许视图共享一个共同的数据源。
class AppData: ObservableObject {
@Published var message = "Hello from environment object"
}
struct ParentView: View {
var body: some View {
ChildView().environmentObject(AppData())
}
}
struct ChildView: View {
@EnvironmentObject var appData: AppData
var body: some View {
Text(appData.message)
}
}
对变化做出反应对于任何现代UI框架来说都是至关重要的。
ReactJS (使用 useEffect):
在React中,useEffect
钩子允许您在函数组件中执行副作用。
const MyComponent = () => {
useEffect(() => {
console.log("Component mounted");
return () => console.log("Component unmounted");
}, []);
return Hello, World!;
};
SwiftUI (使用 onAppear 和 onDisappear):
SwiftUI提供了onAppear和onDisappear修饰符,它们可以附加到视图中以实现类似的功能。
struct MyView: View {
var body: some View {
Text("Hello, World!")
.onAppear {
print("View appeared")
}
.onDisappear {
print("View disappeared")
}
}
}
附带说明一下,在视图首次渲染时调用异步函数,使用 .task
修饰符可能比使用 .onAppear
更好。如果视图在任务完成前已被销毁,任务将自动取消。
导航是任何应用程序的基础。
ReactJS (使用 React Router)
在React中,React Router通常用于导航。
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
const Navigation = () => (
);
SwiftUI (使用 NavigationView 和 NavigationLink)
SwiftUI提供了NavigationView和NavigationLink来创建导航接口。
struct NavigationExampleView: View {
var body: some View {
NavigationView {
NavigationLink(destination: HomeView()) {
Text("Home")
}
}
}
}
SwiftUI带来了一种声明式的UI构建方式,类似于ReactJS,但与Swift集成得更紧密。
了解ReactJS和SwiftUI之间的这些映射可以使两者之间的过渡更加直观。虽然这涉及到一个学习曲线,但了解模式的异同可以使这一过程更加顺利。
请记住,SwiftUI正在迅速发展,因此请及时了解最新的更改和功能。
当您准备好使用HTTP请求并将应用程序连接到远程API时,请查看 “从JavaScript过渡到Swift和SwiftUI?从这个简单的网络层开始”。